叢集索引,資料實際上是按順序儲存的,資料頁就在索引頁上。就好像參考手冊將所有主題按順序編排一樣。一旦找到了所要搜尋的資料,就完成了這次搜尋,對於非叢集索引,索引是安全獨立於資料本身結構的,在索引中找到了尋找的資料,然後通過指標定位到實際的資料。
SQL Server中的索引使用標準的B-樹來儲存他們的資訊,如所示,B-樹通過尋找索引中的一個關鍵之來提供對於資料的快速存取,B-樹以相似的鍵記錄彙總在一起,B不代表二叉(binary),而是代表balanced(平衡的),而B-樹的一個核心作用就是保持樹的平衡。同夥向下遍曆這棵樹以找到一個數值並定位記錄。因為樹是平衡的,所以尋找任何記錄都只需要等量的資源,而且擷取的速度總是一致的—因為從根索引葉索引都具有相同的深度。
索引的中介層次是根據表的行數一級索引行的大小而變化的,如果使用一個較長的鍵(KEY)來建立索引,一個分頁上就只容納較少的條目,因而索引就需要更多分頁(或者說更多層),頁越多那麼尋找就需要話費相對較長的時間來找到所需要的資訊,索引就可能不太有用了。
叢集索引
叢集索引的分葉層級不僅包含了索引鍵,還包含了資料頁。另一種說法資料本身也是叢集索引的一部分,叢集索引基於索引值保持表中的資料有序,表中的資料頁是通過一個被稱作頁鏈(page chain)的雙向連結資料表來維護的,由於實際的資料頁的頁鏈只能按一種方式排序,因此一張表只能擁有一個叢集索引。
這裡可能有一個誤區,有很多介紹SQL Server索引的文檔會告訴讀者:叢集索引按照排序次序(sorted order)物理地儲存資料。如果以為實體儲存體就是磁碟本身的話就會產生誤解。試想如果叢集索引需要按照特定順序在實際的磁碟上維護資料的話,那麼任何修改操作都將會產生相當高昂的代價。當一個頁變滿了需要一分為二的時候,所有後續頁面上的資料都必須向後移動。叢集索引中的排序次序(sorted order)僅僅表示資料頁鏈在邏輯上是有序的。
大多數表都應該需要一個叢集索引。最佳化器非常傾向於採用叢集索引,因為叢集索引能夠直接在分葉層級找到資料。由於定義了資料的邏輯順序,叢集索引能夠特別快的訪問針對範圍值的查詢,查詢最佳化工具能夠發現只有某一段範圍的資料頁需要掃描。
非叢集索引
對於非叢集索引,分葉層級不包含全部的資料。除了索引值之外,每個分葉層級(樹的最底層)中的索引行包含了一個書籤(bookmark),告訴SQL Server可以在那裡找到與索引鍵相應的資料行。一個書籤可能有兩種形式。如果表上存在叢集索引,書籤就是相應的資料行的叢集索引鍵。如果彪是堆(heap)結構,書籤就是一個行表示(row identifier,RID),以“檔案號:頁號:槽號”的格式來定位實際的行。
主鍵(PRIMARY KEY)與叢集索引(CLUSTER INDEX)
嚴格來說,主鍵與叢集索引沒有任何關係,如果要說有話,那就是表中沒有叢集索引的時候,建立的主鍵預設就是叢集索引(除非有特別設定為NOCLUSTER)。
在主鍵與叢集索引的處理方面,注意以下事項:
1、主鍵不與叢集索引分離
2、叢集索引鍵列盡量避免使用int之外的資料類型
3、盡量避免使用複合主鍵
建立索引時的注意事項
1、始終包含叢集索引
當表中不包含叢集索引時,表中的資料是無序的,這會降低資料檢索效率。即使通過索引縮小了資料檢索的範圍,但由於資料本身是無序的,當從表中提取實際資料時,會產生頻繁的定位問題,這也使得SQL Server基本上不會使用無叢集索引表中的索引來檢索資料。
2、保證叢集索引唯一
由於叢集索引是非叢集索引的行定位器,如果它不唯一,則會使行定位器中包含輔助資料,同時也導致從表中提取資料時,需要藉助行定位器中的輔助資料來定位,這會降低處理效率。
3、保證叢集索引最小
每個聚集索引值都是所有非叢集索引的葉結點記錄,它越小,意味著每個非叢集索引的索引葉包含的有效資料越多,這對於提升索引效率很有好處。
4、覆蓋索引
覆蓋索引是指索引中的列包含了資料處理中涉及的所有列,覆蓋索引相當原始表的一個子集,由於這個子集中包含了資料處理涉及的所有列,因此操作這個子集就可以滿足資料處理需要。一般而言,如果大多數處理都只涉及某個大表的某些列,可以考慮為這些列建立覆蓋索引。
覆蓋索引的建立方法是將要包含的列中的關鍵列做為索引鍵列,將其他列做為索引的包含列(使用索引建立語句中的INCLUDE子句)。
5、適量的索引
當資料發生變化時,SQL Server會同步維護相關索引中的資料,過多的索引會加影響資料變更的處理效率。因此,只應該在經常使用的列上建立索引。
適量的索引還體現在對索引列的組合方式的控制上。例如,如果有兩個列col1和col2,這兩個列的組合會產生三種使用方式:單獨使用col1、單獨使用col2及同時使用col1和col2。如果有為每種情況都建立索引,則需要建立三個索引。但也可以只建立一個複合索引(col1, col2),這樣能夠依次滿足col1+col2、col1、col2這三種方式的查詢,其中,col2利用這個查詢會比較勉強(還要配合單獨的統計),可以視實際情況確定是否需要為col2建立單獨的索引。
特別注意:
不要建立重複索引,目前最常見的重複索引是單獨為某個列建立主鍵和叢集索引
與直接從表中提取資料相比,根據索引檢索資料,多了一個索引檢索的過程,這個過程要求能夠盡量縮小資料檢索範圍,並且使用最少的時間,這樣才能真正保證能夠通過索引提高資料檢索效率。
實現上述目的,對於索引鍵列的選擇,應該遵循如下原則:
選擇性原則
選擇性是滿足條件的記錄佔總記錄數的百分比,這個比率應該儘可能低,這樣才能保證通過索引掃描後,只需要從基礎資料表提取很少的資料。
如果這個比率偏高,則不應該考慮在此列上建立索引。
資料密度原則
資料密度是指列值唯一的記錄佔總記錄數的百分比,這個比率越高,則說明此列越適合建立索引。
在考慮資料密度的時候,還要注意資料分布的問題,只有經常檢索的密度高時,才適合建立索引。例如,如果一張表有10萬記錄,雖然某個列不重複的記錄有9萬條,但如果經常檢索的2萬條記錄,其不重複的列值才幾十條的話,這個列是不太適合建立索引的。另一種情況是,整體資料密度不大,但經常檢索的資料的密度大,例如訂單的狀態,一般來說,訂單的狀態就幾種,但已經Close的訂單往往占整個資料的絕大部分,但資料處理的時候,基本上都是檢索未Close的訂單,這種情況下,為訂單的狀態列建立索引還是比較有效(SQL Server 2008中,可以為這種列建立具有更佳效果的篩選索引)。
6、索引鍵列大小
一般不宜為超過100Byte的列建立索引。
7、複合索引鍵列順序
在索引中,索引的順序主要由索引中的每一個鍵列確定,因此,對於複合索引,索引中的列順序是很重要的,應該優先把資料密度大,選擇性列,儲存空間小的列放在索引鍵列的前面。
連結:http://topic.csdn.net/u/20120721/10/b057fc3b-4304-44ee-b7b5-16160f30bacc.html?seed=656570155&r=79190463#r_79190463
作者 Beirut(小愛)