十六、索引

一、索引基本概念

在數據庫中建立索引是爲了加快數據的查詢速度。數據庫中的索引與書籍中的目錄或書後的術語表類
似。在一本書中,利用目錄或術語表可以快速查找所需信息,而無須翻閱整本書。在數據庫中,索引使
對數據的查找不需要對整個表進行掃描,就可以在其中找到所需數據。書籍的索引表是一個詞語列表,
其中註明了包含各個詞的頁碼。而數據庫中的索引是一個表中所包含的列值的列表,其中註明了表中包
含各個值的行數據所在的存儲位置。可以爲表中的單個列建立索引,也可以爲一組列建立索引。索引一
般採用B樹結構。索引由索引項組成,索引項由來自表中每一行的一個或多個列(稱爲搜索關鍵字或索
引關鍵字)組成。B樹按搜索關鍵字排序,可以對組成搜索關鍵字的任何子詞條集合上進行高效搜索。
例如,對於一個由A、B、C三個列組成的索引,可以在A以及A、B和A、B、C上對其進行高效搜索。
例如,假設在Student表的Sno列上建立了一個索引(Sno爲索引項或索引關鍵字),則在索引部分就
有指向每個學號所對應的學生的存儲位置的信息,如下圖。

當數據庫管理系統執行一個在Student表上根據指定的Sno查找該學生信息的語句時,它能夠識別該
表上的索引列(Sno),並首先在索引部分(按學號有序存儲)查找該學號,然後根據找到的學號所指
向的數據的存儲位置,直接檢索出需要的信息。如果沒有索引,則數據庫管理系統需要從Student表的
第一行開始,逐行檢索指定的Sno值。從數據結構的算法知識我們知道有序數據的查找比無序數據的查
找效率要高很多。
    但索引爲查找所帶來的性能好處是有代價的,首先索引在數據庫中會佔用一定的存儲空間來存儲索引信
息。其次,在對數據進行插入、更改和刪除操作時,爲了使索引與數據保持一致,還需要對索引進行相
應維護。對索引的維護是需要花費時間的。
因此,利用索引提高查詢效率是以佔用空間和增加數據更改的時間爲代價的。在設計和創建索引時,應
確保對性能的提高程度大於在存儲空間和處理資源方面的代價。

二、什麼是數據頁?

在數據庫管理系統中,數據一般是按數據頁存儲的,數據頁是一塊固定大小的連續存儲空間。不同的數
據庫管理系統數據頁的大小不同,有的數據庫管理系統數據頁的大小是固定的,比如SQL Server的數據
頁就固定爲8KB;
存放數據的數據頁與存放索引項的數據頁採用的都是通過指針鏈接在一起的方式連接各數據頁,而且在
頁頭包含指向下一頁及前面頁的指針,這樣就可以將表中的全部數據或者索引鏈在一起。數據頁的組織
方式示意圖如圖6-2所示。
 

 

三、索引的存儲結構及分類

索引分爲兩大類,一類是聚集索引(Clustered Index,也稱爲聚簇索引),另一類是非聚集索引
(Non-Clustered Index,也稱爲非聚簇索引)。聚集索引對數據按索引關鍵字值進行物理排序,非聚
集索引不對數據按索引關鍵字值進行物理排序,而只將索引關鍵字按值進行排序。圖6-1所示的索引示
意圖即爲非聚集索引。在SQL Server中聚集索引和非聚集索引都採用B樹結構來存儲索引項,而且都包
含數據頁和索引頁,其中索引頁用來存放索引項和指向下一層的指針,數據頁用來存放數據。不同的數
據庫管理系統中索引的存儲結構不盡相同,本章我們主要介紹SQL Server對索引採用的存儲結構。
B樹結構B樹(Balanced Tree,平衡樹)的最上層節點稱爲根節點(Root Node),最下層節點稱爲葉節點
(Left Node)。在根節點所在層和葉節點所在層之間的層上的節點稱爲中間節點(Intermediate
Node)。B樹結構從根節點開始,以左右平衡的方式存放數據,中間可根據需要分成許多層。 

四、 聚集索引

聚集索引的B樹是自下而上建立的,最下層的葉級節點存放的是數據,因此它即是索引頁,同時也是數
據頁。多個數據頁生成一箇中間層節點的索引頁,然後再由數箇中間層節點的索引頁合成更上層的索引
頁,如此上推,直到生成頂層的根節點的索引頁。生成高一層節點的方法是:從葉級節點開始,高一層
節點中每一行由索引關鍵字值和該值所在的數據頁編號組成,其索引關鍵字值選取的是其下層節點中的
最大或最小索引關鍵字的值。

 

除葉級節點之外的其他層節點,每一個索引行由索引項的值以及這個索引項在下層節點的數據頁編號組
成。
例如,設有職工(Employee)表,其包含的列有:職工號(Eno)、職工名(Ename)和所在部門
(Dept)。假設在Eno列上建有一個聚集索引(按升序排序)。(注:每個節點左上方位置的數字代表
數據頁編號),其中的虛線代表數據頁間的鏈接。
索引的使用代價
當插入或刪除數據時,除了會影響數據的排列順序外,還會引起索引頁中索引項的增加或減少,系統會
對索引頁進行分裂或合併,以保證B樹的平衡性,因此B樹的中間節點數量以及B樹的高度都有可能會發
生變化,但這些調整都是數據庫管理系統自動完成的,因此,在對有索引的表進行插入、刪除和更改操
作時,有可能會降低這些操作的執行性能。 聚集索引對於那些經常要搜索列在連續範圍內的值的查詢
特別有效。使用聚集索引找到包含第一個列值的行後,由於後續要查找的數據值在物理上相鄰而且有
序,因此只要將數據值直接與查找的終止值進行比較即可。 在創建聚集索引之前,應先了解數據是如
何被訪問的,因爲數據的訪問方式直接影響了對索引的使用。如果索引建立的不合適,則非但不能達到
提高數據查詢效率的目的,而且還會影響數據的插入、刪除和更改操作的效率。因此,索引並不是建立
的越多越好(建立索引需要佔用空間,維護索引需要耗費時間),而是要有一些考慮因素。 

聚集索引使用建議

下列情況可考慮創建聚集索引:
1. 包含大量非重複值的列。
2. 使用下列運算符返回一個範圍值的查詢:BETWEEN AND、>、>=、< 和 <=。
3. 經常被用作連接的列,一般來說,這些列是外鍵列。
4. 對ORDER BY或GROUP BY子句中指定的列建立索引,可以使數據庫管理系統在查詢時不必對數
據再進行排序,從而可以提高查詢性能。 對於頻繁進行更改操作的列則不適合建立聚集索引。

五、 非聚集索引

非聚集索引與新華字典的偏旁部首查字法類似。字典的內容(數據)存儲在一個地方, (部首)存儲
在另一個地方。而且字典的內容(數據)並不按部首(索引)的順序存放,但偏旁部首中的每個詞在字
典中都有確切的位置。非聚集索引就類似偏旁部首,而數據就類似於一本字典的的文字。 非聚集索引
的存儲示意圖如下圖:

 

非聚集索引與聚集索引一樣用B樹結構,但有兩個重要差別:
1. 數據不按非聚集索引關鍵字值的順序排序和存儲。
2. 非聚集索引的葉級節點不是存放數據的數據頁。 非聚集索引B樹的葉級節點是索引行。每個索引
行包含非聚集索引關鍵字值以及一個或多個行定位器,這些行定位器指向該關鍵字值對應的數據
行(如果索引不唯一,則可能是多行)。
例如,假設在Employee表的Eno列上建有一個非聚集索引,則數據和其索引B樹的形式。 在建有非聚
集索引的表上查找數據的過程與聚集索引類似,也是從根節點開始逐層向下查找,直到找到葉級節點,
在葉級節點中找到匹配的索引關鍵字值之後,其所對應的行定位器所指位置即是查找數據的存儲位置。
由於非聚集索引並不改變數據的物理存儲順序,因此,可以在一個表上建立多個非聚集索引。就象一本
書可以有多個術語表一樣,如一本介紹園藝的書可能會包含一個植物通俗名稱的術語表和一個植物學名
稱的術語表,因爲這是讀者查找信息的兩種最常用的方法

非聚集索引使用建議

在創建非聚集索引之前,應先了解數據是如何被訪問的,以使建立的索引科學合理。對於下述情況可考
慮創建非聚集索引:
1. 包含大量非重複值的列。如果某列只有很少的非重複值,比如只有1和0,則不對這些列建立非聚
集索引。
2. 經常作爲查詢條件使用的列。
3. 經常作爲連接和分組條件的列。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章