聚集索引
聚集索引對(duì)于從表中檢索一定范圍的數(shù)據(jù)值非常有用。非聚集索引最適于檢索特定行,而聚集索引最適于檢索一定范圍的行。但是,由于每個(gè)表只允許使用一個(gè)聚集索引,因此按照這個(gè)簡(jiǎn)單的邏輯來(lái)確定要?jiǎng)?chuàng)建哪種類型的索引并不總能成功。對(duì)于該問(wèn)題有一個(gè)簡(jiǎn)單的物理原因。對(duì)于聚集索引 B 樹(shù)結(jié)構(gòu)的上部(非葉層),如果像對(duì)它們的非聚集索引部分那樣組織,則聚集索引的底層由表的實(shí)際 8 KB 數(shù)據(jù)頁(yè)組成。但這種情況有一個(gè)例外,那就是在視圖的基礎(chǔ)上創(chuàng)建聚集索引時(shí)。因?yàn)閷⒃谙旅娼榻B索引視圖,所以我們將討論針對(duì)實(shí)際表創(chuàng)建的聚集索引。在針對(duì)表創(chuàng)建聚集索引時(shí),會(huì)按與索引搜索鍵相同的順序讀取與該表關(guān)聯(lián)的數(shù)據(jù)、對(duì)這些數(shù)據(jù)進(jìn)行排序,并會(huì)在物理上將它們存回?cái)?shù)據(jù)庫(kù)。因?yàn)樵摫淼臄?shù)據(jù)只能按照一種順序保存到存儲(chǔ)器中,不會(huì)導(dǎo)致重復(fù),所以符合一個(gè)聚集的限制。
聚集索引和性能
聚集索引有一些會(huì)影響性能的固有特征。
在使用聚集索引根據(jù)搜索鍵來(lái)檢索 SQL Server 數(shù)據(jù)時(shí),不需要指針跳轉(zhuǎn)(會(huì)導(dǎo)致硬盤(pán)上的位置可能不按順序更改)來(lái)檢索關(guān)聯(lián)的數(shù)據(jù)頁(yè)。這是由于聚集索引的葉層實(shí)際上就是關(guān)聯(lián)的數(shù)據(jù)頁(yè)。
如前所述,葉層(當(dāng)然也包括表或索引視圖的數(shù)據(jù))在物理上會(huì)按照與搜索鍵相同的順序進(jìn)行排序和存儲(chǔ)。因?yàn)榫奂饕娜~層包含表的實(shí)際 8 KB 數(shù)據(jù)頁(yè),所以整個(gè)表的行數(shù)據(jù)會(huì)按照由聚集索引確定的順序以物理方式排列在磁盤(pán)驅(qū)動(dòng)器上。這就會(huì)在根據(jù)聚集索引的值從該表中提取大量行(至少大于 64 KB)時(shí)帶來(lái)潛在的 I/O 性能優(yōu)勢(shì),因?yàn)槭褂玫氖琼樞虼疟P(pán) I/O(除非該表上發(fā)生了頁(yè)拆分,這種情況將在題為“FILLFACTOR 和 PAD_INDEX”的一節(jié)中討論)。正因?yàn)槿绱耍栽跈z索大量行時(shí),一定要根據(jù)將用于執(zhí)行范圍掃描的列來(lái)對(duì)表選取聚集索引。
表中與聚集索引相關(guān)聯(lián)的行必須按照與索引搜索鍵相同的順序排序和存儲(chǔ),這一點(diǎn)具有以下意義:
- 在您創(chuàng)建聚集索引時(shí),表會(huì)被復(fù)制,表中的數(shù)據(jù)會(huì)被排序,然后,原來(lái)的表會(huì)被刪除。所以,數(shù)據(jù)庫(kù)中必須有足夠的空閑空間來(lái)存放數(shù)據(jù)的副本。
- 在默認(rèn)情況下,會(huì)在創(chuàng)建索引時(shí)對(duì)表中的數(shù)據(jù)進(jìn)行排序。但是,如果數(shù)據(jù)已按正確順序排過(guò)序,則會(huì)自動(dòng)跳過(guò)排序操作。這樣就可以顯著加快索引創(chuàng)建過(guò)程。
- 將數(shù)據(jù)裝載到表中時(shí)的順序應(yīng)盡可能與您計(jì)劃用于生成聚集索引的搜索鍵的順序相同。對(duì)于大表(例如那些通常會(huì)成為數(shù)據(jù)倉(cāng)庫(kù)特征的表),該方法將大大加速索引創(chuàng)建過(guò)程,從而縮短您處理初始數(shù)據(jù)裝載所需的時(shí)間。只要表中的行仍保持未創(chuàng)建聚集索引時(shí)所排的順序,就可以在除去和重建聚集索引時(shí)可以使用該方法。任何行排序有誤,操作都會(huì)被取消,會(huì)出現(xiàn)相應(yīng)的錯(cuò)誤信息,而且不會(huì)創(chuàng)建索引。
- 同樣,針對(duì)排過(guò)序的數(shù)據(jù)生成聚集索引時(shí)所需要的 I/O 也少得多,這是因?yàn)椴槐貜?fù)制數(shù)據(jù)、對(duì)數(shù)據(jù)進(jìn)行排序、將數(shù)據(jù)存回?cái)?shù)據(jù)庫(kù),然后刪除舊表數(shù)據(jù),而是會(huì)將數(shù)據(jù)留在原來(lái)分配給它的擴(kuò)展盤(pán)區(qū)中。索引擴(kuò)展盤(pán)區(qū)只是添加到數(shù)據(jù)庫(kù)中來(lái)存儲(chǔ)頂層節(jié)點(diǎn)和中間節(jié)點(diǎn)。
注意 針對(duì)大表生成索引的首選方法是:先生成聚集索引,然后生成非聚集索引。這樣,就不會(huì)因?yàn)閿?shù)據(jù)移動(dòng)而需要重新生成非聚集索引。在除去所有索引時(shí),首先會(huì)除去非聚集索引,最后除去聚集索引。這樣,就不需要重新生成索引。
非聚集索引
非聚集索引最適于根據(jù)特定的鍵值,從大型 SQL Server 表中提取少數(shù)幾個(gè)具有良好選擇性的行。如前所述,非聚集索引是由 8 KB 索引頁(yè)形成的二進(jìn)制樹(shù)。索引頁(yè)二進(jìn)制樹(shù)的底層或葉層包含組成該索引的列中的所有數(shù)據(jù)。在使用非聚集索引根據(jù)鍵值的匹配項(xiàng)從表中檢索信息時(shí),會(huì)遍歷索引的 B 樹(shù),直到在索引的葉層找到鍵的匹配項(xiàng)。如果需要表中不構(gòu)成索引的列,指針就會(huì)跳轉(zhuǎn)。這種指針跳轉(zhuǎn)將有可能需要針對(duì)磁盤(pán)執(zhí)行非順序 I/O 操作。它甚至可能需要從另一磁盤(pán)中讀取數(shù)據(jù),尤其是在表及其伴隨的索引 B 樹(shù)很大時(shí)。如果多個(gè)指針指向同一個(gè) 8 KB 數(shù)據(jù)頁(yè),對(duì) I/O 性能的影響就會(huì)比較小,因?yàn)橹恍鑼⒃擁?yè)讀入數(shù)據(jù)緩存一次。如果 SQL 查詢涉及到用非聚集索引進(jìn)行搜索,則對(duì)于對(duì)該查詢返回的每一行,至少需要一次指針跳轉(zhuǎn)。
注意 由于指針每次跳轉(zhuǎn)都會(huì)帶來(lái)與之相關(guān)的開(kāi)銷,因此非聚集索引更適于處理從表中只返回一行或幾行的查詢。聚集索引更適于處理需要一系列行的查詢。
聚集索引和非聚集索引均可用于強(qiáng)制表內(nèi)的唯一性,方法是在現(xiàn)有表上創(chuàng)建索引時(shí)指定 UNIQUE 關(guān)鍵字。確保表內(nèi)唯一性的另一種方法是使用 UNIQUE 約束。如同唯一索引,UNIQUE 約束強(qiáng)制一組列中各值的唯一性。實(shí)際上,UNIQUE 約束的賦值自動(dòng)創(chuàng)建基礎(chǔ)唯一索引,以利于強(qiáng)制該約束。由于唯一性可以作為 CREATE TABLE 語(yǔ)句的一部分來(lái)加以定義和記錄,因此,UNIQUE 約束通常優(yōu)先于單獨(dú)唯一索引的創(chuàng)建。
索引視圖
索引視圖是為了實(shí)現(xiàn)快速訪問(wèn)而將其結(jié)果持續(xù)存放于數(shù)據(jù)庫(kù)內(nèi)并創(chuàng)建索引的視圖。與任何其他視圖一樣,索引視圖也依靠基表來(lái)提供視圖數(shù)據(jù)。此類相關(guān)性意味著,如果更改為索引視圖提供數(shù)據(jù)的基表,索引視圖可能變得無(wú)效。例如,重命名為視圖提供數(shù)據(jù)的列會(huì)使該視圖無(wú)效。為了避免此類問(wèn)題,SQL Server 支持創(chuàng)建具有架構(gòu)綁定的視圖。架構(gòu)綁定禁止對(duì)表或列進(jìn)行任何會(huì)使視圖無(wú)效的修改。使用視圖設(shè)計(jì)器創(chuàng)建的索引視圖自動(dòng)獲得架構(gòu)綁定,因?yàn)?SQL Server 要求該索引視圖具有架構(gòu)綁定。架構(gòu)綁定并不是說(shuō)您不能修改視圖;它的意思是您不能按更改視圖結(jié)果集的方式來(lái)修改基礎(chǔ)表或視圖。另外,就像計(jì)算列上的索引一樣,索引視圖也必須有確定性、精確,且不得包含 text、ntext 或 image 等列。
索引視圖在基礎(chǔ)數(shù)據(jù)不經(jīng)常更新的情況下效果最佳。維護(hù)索引視圖的成本可能高于維護(hù)表索引的成本。如果基礎(chǔ)數(shù)據(jù)更新頻繁,索引視圖數(shù)據(jù)的維護(hù)成本就可能超過(guò)使用索引視圖帶來(lái)的性能收益。