索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速存取資料庫表中的特定資訊。其實道理很簡單,比如我們要從字典中尋找一個字,那麼這個字典就是我們所要面對的資料庫,索引就好比是字典前面的拼音或者部首索引表,當需要查詢一個字的時候我們首先去檢索拼音或者部首索引表,然後再去字典中尋找具體的位置,這樣我們就加快資料庫的查詢速度。
索引分為聚簇索引和非聚簇索引兩種,聚簇索引是按照資料存放的物理位置為順序的,而非聚簇索引就不一樣了(下一篇文章將介紹常見的索引)。顯而易見的字典本身的內容以及前面的拼音檢索表就是聚簇索引,因為他們都是按照26個字母的順序排列的。而後面的部首檢索表就是一個非聚簇索引,他並不是按照每個字所在的具體的位置排列的,而是通過特定的排列規則進行排序的。
使用索引的好處就是查詢起來效率高了,但任何事物都有正反兩方面,使用索引也會降低資料庫的效率,這裡的效率是指在增刪改的時候會比不講索引效率慢。道理很簡單如果一本字典隨時在變化那麼需要變的不僅僅是這個字典的內容還有就是這個字典前面的拼音或者部首檢字表。所以有索引的情況下增刪改的效率肯定會降低的。
而且需要注意的是有索引不一定效率就會提升,試想一本字典可以把所有的字全部放在檢索表中(實際上這是沒有意義的)這樣的話如果要查詢一個字那麼就相當於查詢了多次,首先在龐大的檢索表中查詢一遍,然後再去資料庫中查詢這個字的詳細內容,這要比直接從字典查詢效率要低。
建立索引不一定就提高查詢的效率,這取決於索引是否合理,以及查詢是否用到索引。並非是在任何欄位上簡單地建立索引就能提高查詢速度。索引的建立,會帶來更多的系統開銷,因為系統要耗費資源去維護它,如果建立了沒有用到的索引,不適當的索引,過多的索引,反而會導致查詢效能下降。總之索引的建立,要看錶的結構,資料的分布,還有你要用到哪些資料,如果把索引建立在你根本不需要的資料列上,是根本不會發揮作用的舉例如下:
(1)全表掃描
只在主鍵上建立叢集索引:
Selectid,name,dept,emdate from person 用時:20546毫秒(即:21秒)
不在主鍵上建立叢集索引,只建普通索引
Selectid,name,dept,emdate from person 用時:17923毫秒(即:18秒)
以上查詢執行的實際上索引不會發揮作用,因為提取的是全部資料。叢集索引在這裡會耗費更多的資源,所以會看到,不建立叢集索引比建立叢集索引還要快
(2):按日期進行過濾(用到索引)
在主鍵上建立叢集索引,在emdate上建立非叢集索引:
Select id,name,dept,emdatefrom person where emdate>dateadd(day,+1,getdate()) 用時:12376毫秒(12秒)
在主鍵上建立叢集索引,在emdate上沒有索引:
selectid,name,dept,emdate from person where emdate>dateadd(day,+1,getdate()) 用時:21296毫秒(21秒)
在主鍵上建立非叢集索引,在emdate上建立非叢集索引:
selectid,name,dept,emdate from person where emdate>dateadd(day,+1,getdate()) 用時:11590毫秒(12秒)
在主鍵上建立非叢集索引,在emdate上建立叢集索引:
selectid,name,dept,emdate from person where emdate>dateadd(day,+1,getdate()) andemdate<dateadd(day,+3,getdate()) 用時:5233毫秒(5秒)
雖然每條語句提取出來的都是30萬條資料,各種情況的差異卻是比較大的,特別是將叢集索引建立在日期列時的差異。事實上,如果您的資料庫真的有幾千萬條記錄的話,差距會更明顯。
關於索引方面的系統最佳化和其他最佳化一樣,都需要根據實際的情況而定,瞭解了索引的原理那麼就能對症下藥,合理的建立索引進而提高系統的查詢效率。