用戶對(duì)數(shù)據(jù)庫(kù)最頻繁的操作是進(jìn)行數(shù)據(jù)查詢。一般情況下,數(shù)據(jù)庫(kù)在進(jìn)行查詢操作時(shí)需要對(duì)整個(gè)表進(jìn)行數(shù)據(jù)搜索。當(dāng)表中的數(shù)據(jù)很多時(shí),搜索數(shù)據(jù)就需要很長(zhǎng)的時(shí)間,這就造成了服務(wù)器的資源浪費(fèi)。為了提高檢索數(shù)據(jù)的能力,數(shù)據(jù)庫(kù)引入了索引機(jī)制。本章將介紹索引的概念及其創(chuàng)建與管理。
8.1.1 索引的概念
索引是一個(gè)單獨(dú)的、物理的數(shù)據(jù)庫(kù)結(jié)構(gòu),它是某個(gè)表中一列或若干列值的集合和相應(yīng)的指向表中物理標(biāo)識(shí)這些值的數(shù)據(jù)頁(yè)的邏輯指針清單。索引是依賴于表建立的,它提供了數(shù)據(jù)庫(kù)中編排表中數(shù)據(jù)的內(nèi)部方法。一個(gè)表的存儲(chǔ)是由兩部分組成的,一部分用來(lái)存放表的數(shù)據(jù)頁(yè)面,另一部分存放索引頁(yè)面。索引就存放在索引頁(yè)面上,通常,索引頁(yè)面相對(duì)于數(shù)據(jù)頁(yè)面來(lái)說(shuō)小得多。當(dāng)進(jìn)行數(shù)據(jù)檢索時(shí),系統(tǒng)先搜索索引頁(yè)面,從中找到所需數(shù)據(jù)的指針,再直接通過(guò)指針從數(shù)據(jù)頁(yè)面中讀取數(shù)據(jù)。從某種程度上,可以把數(shù)據(jù)庫(kù)看作一本書,把索引看作書的目錄,通過(guò)目錄查找書中的信息,顯然較沒(méi)有目錄的書方便、快捷。
索引和關(guān)鍵字及約束有較大的聯(lián)系。關(guān)鍵字可以分為兩類:一種是邏輯關(guān)鍵字,即在 “數(shù)據(jù)庫(kù)基礎(chǔ)章”節(jié)中介紹的;另一種是物理關(guān)鍵字,它用來(lái)定義索引的列,也即索引。
8.1.2 索引的結(jié)構(gòu)
(1) 索引的B-樹(shù)結(jié)構(gòu)
SQL Server 中的索引是以B-樹(shù)結(jié)構(gòu)來(lái)維護(hù)的,如圖8-1 所示。B-樹(shù)是一個(gè)多層次、自維護(hù)的結(jié)構(gòu)。一個(gè)B-樹(shù)包括一個(gè)頂層,稱為根節(jié)點(diǎn)(Root Node);0 到多個(gè)中間層(Intermediate);一個(gè)底層(Level 0),底層中包括若干葉子節(jié)點(diǎn)(Leaf Node)。在圖 8-1 中,每個(gè)方框代表一個(gè)索引頁(yè),索引列的寬度越大,B-樹(shù)的深度越深,即層次越多,

讀取記錄所要訪問(wèn)的索引頁(yè)就越多。也就是說(shuō),數(shù)據(jù)查詢的性能將隨索引列層次數(shù)目的增加而降低。 圖8-1 索引的B-樹(shù)結(jié)構(gòu)
在SQL Server 的數(shù)據(jù)庫(kù)中按存儲(chǔ)結(jié)構(gòu)的不同將索引分為兩類:簇索引(Clustered Index)和非簇索引(Nonclustered Index)。
(2) 簇索引簇索引對(duì)表的物理數(shù)據(jù)頁(yè)中的數(shù)據(jù)按列進(jìn)行排序,然后再重新存儲(chǔ)到磁盤上,即簇索引與數(shù)據(jù)是混為一體,的它的葉節(jié)點(diǎn)中存儲(chǔ)的是實(shí)際的數(shù)據(jù)。由于簇索引對(duì)表中的數(shù)據(jù)一一進(jìn)行了排序,因此用簇索引查找數(shù)據(jù)很快。但由于簇索引將表的所有數(shù)據(jù)完全重新排列了,它所需要的空間也就特別大,大概相當(dāng)于表中數(shù)據(jù)所占空間的120% 。表的數(shù)據(jù)行只能以一種排序方式存儲(chǔ)在磁盤上,所以一個(gè)表只能有一個(gè)簇索引。
(3) 非簇索引非簇索引具有與表的數(shù)據(jù)完全分離的結(jié)構(gòu),使用非簇索引不用將物理數(shù)據(jù)頁(yè)中的數(shù)據(jù)按列排序。非簇索引的葉節(jié)點(diǎn)中存儲(chǔ)了組成非簇索引的關(guān)鍵字的值和行定位器。行定位器的結(jié)構(gòu)和存儲(chǔ)內(nèi)容取決于數(shù)據(jù)的存儲(chǔ)方式。如果數(shù)據(jù)是以簇索引方式存儲(chǔ)的,則行定位器中存儲(chǔ)的是簇索引的索引鍵;如果數(shù)據(jù)不是以簇索引方式存儲(chǔ)的,這種方式又稱為堆存儲(chǔ)方式(Heap Structure),則行定位器存儲(chǔ)的是指向數(shù)據(jù)行的指針。非簇索引將行定位器按關(guān)鍵字的值用一定的方式排序,這個(gè)順序與表的行在數(shù)據(jù)頁(yè)中的排序是不匹配的。由于非簇索引使用索引頁(yè)存儲(chǔ)因此它比簇索引需要更多的存儲(chǔ)空間且檢索效率較低但一個(gè)表只能建一個(gè)簇索引,當(dāng)用戶需要建立多個(gè)索引時(shí)就需要使用非簇索引了。從理論上講,一個(gè)表最多可以建249 個(gè)非簇索引。
8.1.1 索引的概念
索引是一個(gè)單獨(dú)的、物理的數(shù)據(jù)庫(kù)結(jié)構(gòu),它是某個(gè)表中一列或若干列值的集合和相應(yīng)的指向表中物理標(biāo)識(shí)這些值的數(shù)據(jù)頁(yè)的邏輯指針清單。索引是依賴于表建立的,它提供了數(shù)據(jù)庫(kù)中編排表中數(shù)據(jù)的內(nèi)部方法。一個(gè)表的存儲(chǔ)是由兩部分組成的,一部分用來(lái)存放表的數(shù)據(jù)頁(yè)面,另一部分存放索引頁(yè)面。索引就存放在索引頁(yè)面上,通常,索引頁(yè)面相對(duì)于數(shù)據(jù)頁(yè)面來(lái)說(shuō)小得多。當(dāng)進(jìn)行數(shù)據(jù)檢索時(shí),系統(tǒng)先搜索索引頁(yè)面,從中找到所需數(shù)據(jù)的指針,再直接通過(guò)指針從數(shù)據(jù)頁(yè)面中讀取數(shù)據(jù)。從某種程度上,可以把數(shù)據(jù)庫(kù)看作一本書,把索引看作書的目錄,通過(guò)目錄查找書中的信息,顯然較沒(méi)有目錄的書方便、快捷。
索引和關(guān)鍵字及約束有較大的聯(lián)系。關(guān)鍵字可以分為兩類:一種是邏輯關(guān)鍵字,即在 “數(shù)據(jù)庫(kù)基礎(chǔ)章”節(jié)中介紹的;另一種是物理關(guān)鍵字,它用來(lái)定義索引的列,也即索引。
8.1.2 索引的結(jié)構(gòu)
(1) 索引的B-樹(shù)結(jié)構(gòu)
SQL Server 中的索引是以B-樹(shù)結(jié)構(gòu)來(lái)維護(hù)的,如圖8-1 所示。B-樹(shù)是一個(gè)多層次、自維護(hù)的結(jié)構(gòu)。一個(gè)B-樹(shù)包括一個(gè)頂層,稱為根節(jié)點(diǎn)(Root Node);0 到多個(gè)中間層(Intermediate);一個(gè)底層(Level 0),底層中包括若干葉子節(jié)點(diǎn)(Leaf Node)。在圖 8-1 中,每個(gè)方框代表一個(gè)索引頁(yè),索引列的寬度越大,B-樹(shù)的深度越深,即層次越多,

讀取記錄所要訪問(wèn)的索引頁(yè)就越多。也就是說(shuō),數(shù)據(jù)查詢的性能將隨索引列層次數(shù)目的增加而降低。 圖8-1 索引的B-樹(shù)結(jié)構(gòu)
在SQL Server 的數(shù)據(jù)庫(kù)中按存儲(chǔ)結(jié)構(gòu)的不同將索引分為兩類:簇索引(Clustered Index)和非簇索引(Nonclustered Index)。
(2) 簇索引簇索引對(duì)表的物理數(shù)據(jù)頁(yè)中的數(shù)據(jù)按列進(jìn)行排序,然后再重新存儲(chǔ)到磁盤上,即簇索引與數(shù)據(jù)是混為一體,的它的葉節(jié)點(diǎn)中存儲(chǔ)的是實(shí)際的數(shù)據(jù)。由于簇索引對(duì)表中的數(shù)據(jù)一一進(jìn)行了排序,因此用簇索引查找數(shù)據(jù)很快。但由于簇索引將表的所有數(shù)據(jù)完全重新排列了,它所需要的空間也就特別大,大概相當(dāng)于表中數(shù)據(jù)所占空間的120% 。表的數(shù)據(jù)行只能以一種排序方式存儲(chǔ)在磁盤上,所以一個(gè)表只能有一個(gè)簇索引。
(3) 非簇索引非簇索引具有與表的數(shù)據(jù)完全分離的結(jié)構(gòu),使用非簇索引不用將物理數(shù)據(jù)頁(yè)中的數(shù)據(jù)按列排序。非簇索引的葉節(jié)點(diǎn)中存儲(chǔ)了組成非簇索引的關(guān)鍵字的值和行定位器。行定位器的結(jié)構(gòu)和存儲(chǔ)內(nèi)容取決于數(shù)據(jù)的存儲(chǔ)方式。如果數(shù)據(jù)是以簇索引方式存儲(chǔ)的,則行定位器中存儲(chǔ)的是簇索引的索引鍵;如果數(shù)據(jù)不是以簇索引方式存儲(chǔ)的,這種方式又稱為堆存儲(chǔ)方式(Heap Structure),則行定位器存儲(chǔ)的是指向數(shù)據(jù)行的指針。非簇索引將行定位器按關(guān)鍵字的值用一定的方式排序,這個(gè)順序與表的行在數(shù)據(jù)頁(yè)中的排序是不匹配的。由于非簇索引使用索引頁(yè)存儲(chǔ)因此它比簇索引需要更多的存儲(chǔ)空間且檢索效率較低但一個(gè)表只能建一個(gè)簇索引,當(dāng)用戶需要建立多個(gè)索引時(shí)就需要使用非簇索引了。從理論上講,一個(gè)表最多可以建249 個(gè)非簇索引。