天天看點

sql中聚集索引與非聚集索引的總結文檔-1

1.概念

SQL SERVER提供了兩種索引:聚集索引和非聚集索引。其中聚集索引表示表中存儲的資料按照索引的順序存儲,檢索效率比非聚集索引高,但對資料更新影響較 大。非聚集索引表示資料存儲在一個地方,索引存儲在另一個地方,索引帶有指針指向資料的存儲位置,非聚集索引檢索效率比聚集索引低,但對資料更新影響較小。

2.一個通俗的舉例,說明兩者的差別

    其實,我們的漢語字典的正文本身就是一個聚集索引。比如,我們要查“安”字,就會很自然地翻開字典的前幾頁,因為“安”的拼音是“an”,而按照拼音排序 漢字的字典是以英文字母“a”開頭并以“z”結尾的,那麼“安”字就自然地排在字典的前部。如果您翻完了所有以“a”開頭的部分仍然找不到這個字,那麼就 說明您的字典中沒有這個字;同樣的,如果查“張”字,那您也會将您的字典翻到最後部分,因為“張”的拼音是“zhang”。也就是說,字典的正文部分本身 就是一個目錄,您不需要再去查其他目錄來找到您需要找的内容。我們把這種正文内容本身就是一種按照一定規則排列的目錄稱為“聚集索引”。

    如果您認識某個字,您可以快速地從自動中查到這個字。但您也可能會遇到您不認識的字,不知道它的發音,這時候,您就不能按照剛才的方法找到您要查的字,而 需要去根據“偏旁部首”查到您要找的字,然後根據這個字後的頁碼直接翻到某頁來找到您要找的字。但您結合“部首目錄”和“檢字表”而查到的字的排序并不是 真正的正文的排序方法,比如您查“張”字,我們可以看到在查部首之後的檢字表中“張”的頁碼是672頁,檢字表中“張”的上面是“馳”字,但頁碼卻是63 頁,“張”的下面是“弩”字,頁面是390頁。很顯然,這些字并不是真正的分别位于“張”字的上下方,現在您看到的連續的“馳、張、弩”三字實際上就是他 們在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我們可以通過這種方式來找到您所需要的字,但它需要兩個過程,先找到目錄中的結果,然後 再翻到您所需要的頁碼。我們把這種目錄純粹是目錄,正文純粹是正文的排序方式稱為“非聚集索引”。

3.索引的類型

聚集索引

非聚集索引,其又包括兩種:堆上的非聚集索引、聚集表上的非聚集索引

解釋一下下非聚集索引的差別(個人了解的):

1)聚集表上的非聚集索引:建立非聚集索引之前首頁要建立聚集索引

2)堆上的非聚集索引:堆是在其上沒有聚集索引的一個表。在這種情況下,基于行的區段、頁以及行偏移量(偏移頁頂部的位置)的組合建立唯一的辨別符,或者稱為行ID(RID)。如果沒有可用的聚集鍵(沒有聚集索引),那麼RID是唯一必要的内容。堆表并不是B樹結構。

(官方文檔上的)

3)基礎表的資料行不按非聚集鍵的順序排序和存儲

4)非聚集索引的葉層是由索引頁而不是由資料頁組成

4.非聚集索引的結構:

sql中聚集索引與非聚集索引的總結文檔-1

5.聚集索引執行個體

由于ID列是聚集索引,是以根據ID查找,B樹結構的優點就充分發揮了出來,隻需要2次實體讀就能夠定位到資料。

 而‘标題’列上沒有索引,是以還是需要預讀19次(還是聚集表掃描)才能定位到資料。

sql中聚集索引與非聚集索引的總結文檔-1

6.非聚集索引執行個體

1、因為在SQL Server中一頁隻是8K,頁面空間有限,是以一行所包含的列數越少,它能儲存的行就越多。非聚集索引通常不包含表中所有的列,它一般隻包含非常少數的列。是以,一個頁上将能包含比表行(所有的列)更多行的非聚集索引。是以,同樣讀取一頁,在非聚集索引中可能包含200行,但是在表中可能隻有10行,具體資料有表行的大小以及非聚集列的大小确定。

  2、非聚集索引的另一個好處是,它有一個獨立于資料表的結構,是以可以被放置在不同的檔案組,使用不同的I/O路徑,這意味着SQL Server可以并行通路索引和表,使查找更快速。

  下面說明一下,非聚集索引的好處:

24,14,12  11,20,9   15,15,10 16,13,7 2,26,17  21,18,22  19,6,5  1,8,3  27,4,23

假設有一個單列的表,共有27行,每一頁上存了3行。沒有順序,假如我們要從中查找值為5的行,那麼需要的讀次數為9,因為它必須掃描到最後一頁,才能夠确定所有頁都不存在值為5的行了。

  假如建立了非聚集索引:

1,2,3  4,5,6 7,8,9 10,11,12  13,14,15 16,17,18  19,20,21  22,23,24 25,26,27

再次查找值為5的行,那麼需要的讀次數為2,為什麼?因為非聚集索引是有順序的,當SQL Server讀取到值為6的那一行時,就知道不必再讀下去了。那麼如果要讀取值為25的頁呢?還是需要9個讀操作。因為它剛巧就在最後一頁。恰好這個東西,可以通過B樹結構來優化。B樹算法最小化了定位所需的鍵值通路的頁面數量,進而加速了資料通路過程.

7.非聚集索引的開銷

  索引給性能帶來的好處有一定的代價。有索引的表需要更多的存儲和記憶體空間容納資料頁面之外的索引頁面。資料的增删改可能會花費更長的時間,需要更多的處理時間以維護不斷變化的表的索引。如果一個INSERT語句添加一行到表中,那麼它也必須添加一行到索引結構中。如果索引是一個聚集索引,開銷可能會更大,因為行必須以正确的順序添加到資料頁面(當然分int聚集列和string聚集列會不同)。UPDATE和DELETE類似。

  雖然索引對增删改有一定的影響,但是别忘了,要UPDATE或DELETE一行的前提是必須找到一行,是以索引實際上對于有複雜WHERE條件的UPDATE或DELETE也是有幫助的。在使用索引定位一行的有效性通常能彌補更新索引所帶來的額外開銷。除非索引設計不合理。

關于索引的幾個要點:

  1. 群集索引通常比非群集索引快(書簽)。
  2. 僅在将得到進階别選擇性的列(90%以上)上放置非群集索引。
  3. 所有的資料操作語言(DML:INSERT、UPDATE、DELETE、SELECT)語句可以通過索引獲益,但是插入、删除和更新會因為索引而變慢。
  4. 索引會占用空間。
  5. 僅當索引中的第一列和查詢相關時才使用索引。
  6. 索引的負面影響和它的正面影響一樣多 - 是以隻建立需要的索引。
  7. 索引可為非結構化XML資料提供結構化的資料性能,但是要記住,和其他索引一樣,會涉及到系統開銷。

本文從以下三篇文章中摘抄出來的

http://www.cnblogs.com/kissdodog/archive/2013/06/12/3132380.html

http://jingyan.baidu.com/article/e73e26c0f1e82d24acb6a75d.html

http://msdn.microsoft.com/zh-cn/library/ms177484(v=sql.105).aspx