彙集索引和非彙集索引的區別

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

方法/步驟

  1. 彙集索引:該索引中鍵值的邏輯順序決定了表中相應行的物理順序。

         彙集索引肯定表中數據的物理順序。彙集索引相似於電話簿,後者按姓氏排列數據。因爲彙集索引規定數據在表中的物理存儲順序,所以一個表只能包含一個彙集索引。但該索引能夠包含多個列(組合索引),就像電話簿按姓氏和名字進行組織同樣。java

  2. 彙集索引使用注意事項 

         定義彙集索引鍵時使用的列越少越好。數據庫

         • 包含大量非重複值的列。性能

        .• 使用下列運算符返回一個範圍值的查詢:BETWEEN、>、>=、< 和 <=。大數據

         •  被連續訪問的列。指針

         •  回大型結果集的查詢。blog

         • 常常被使用聯接或 GROUP BY 子句的查詢訪問的列;通常來講,這些是外鍵列。對 ORDER BY 或  GROUP BY 子句中指定的列進行索引,可使 SQL Server 沒必要對數據進行排序,由於這些行已經排序。這樣能夠提升查詢性能。排序

         •  OLTP 類型的應用程序,這些程序要求進行很是快速的單行查找(通常經過主鍵)。應在主鍵上建立彙集索引。 索引

  3. 彙集索引不適用於: 

         • 頻繁更改的列 。這將致使整行移動(由於 SQL Server  必須按物理順序保留行中的數據值)。這一點要特別注意,由於在大數據量事務處理系統中數據是易失的。 事務

         • 寬鍵 。來自彙集索引的鍵值由全部非彙集索引做爲查找鍵使用,所以存儲在每一個非彙集索引的葉條目內。 

  4. 非彙集索引:數據存儲在一個地方,索引存儲在另外一個地方,索引帶有指針指向數據的存儲位置。

          非彙集索引中的項目按索引鍵值的順序存儲,而表中的信息按另外一種順序存儲(這能夠由彙集索引規定)。對於非彙集索引,能夠爲在表非彙集索引中查找數據時經常使用的每一個列建立一個非彙集索引。有些書籍包含多個索引。例如,一本介紹園藝的書可能會包含一個植物通俗名稱索引,和一個植物學名索引,由於這是讀者查找信息的兩種最經常使用的方法。 

  5. 個通俗的舉例,說明二者的區別 

          其實,咱們的漢語字典的正文自己就是一個彙集索引。好比,咱們要查「安」字,就會很天然地翻開字典的前幾頁,由於「安」的拼音是「an」,而按照拼音排序漢字的字典是以英文字母「a」開頭並以「z」結尾的,那麼「安」字就天然地排在字典的前部。若是您翻完了全部以「a」開頭的部分仍然找不到這個字,那麼就說明您的字典中沒有這個字;一樣的,若是查「張」字,那您也會將您的字典翻到最後部分,由於「張」的拼音是「zhang」。也就是說,字典的正文部分自己就是一個目錄,您不須要再去查其餘目錄來找到您須要找的內容。咱們把這種正文內容自己就是一種按照必定規則排列的目錄稱爲「彙集索引」。

        若是您認識某個字,您能夠快速地從自動中查到這個字。但您也可能會遇到您不認識的字,不知道它的發音,這時候,您就不能按照剛纔的方法找到您要查的字,而須要去根據「偏旁部首」查到您要找的字,而後根據這個字後的頁碼直接翻到某頁來找到您要找的字。但您結合「部首目錄」和「檢字表」而查到的字的排序並非真正的正文的排序方法,好比您查「張」字,咱們能夠看到在查部首以後的檢字表中「張」的頁碼是672頁,檢字表中「張」的上面是「馳」字,但頁碼倒是63頁,「張」的下面是「弩」字,頁面是390頁。很顯然,這些字並非真正的分別位於「張」字的上下方,如今您看到的連續的「馳、張、弩」三字實際上就是他們在非彙集索引中的排序,是字典正文中的字在非彙集索引中的映射。咱們能夠經過這種方式來找到您所須要的字,但它須要兩個過程,先找到目錄中的結果,而後再翻到您所須要的頁碼。咱們把這種目錄純粹是目錄,正文純粹是正文的排序方式稱爲「非彙集索引」。 

  6. 下面這張圖總結了什麼時候使用匯集索引或非彙集索引: 
    彙集索引和非彙集索引的區別有哪些
  7. 下面說說索引使用的幾個誤區和問題

    第一:彙集索引的約束是惟一性,是否要求字段也是惟一的呢?

         分析:若是認爲是的朋友,多是受系統默認設置的影響,通常咱們指定一個表的主鍵,若是這個表以前沒有彙集索引,同時創建主鍵時候沒有強制指定使用非彙集索引,SQL會默認在此字段上建立一個彙集索引,而主鍵都是惟一的,因此理所固然的認爲建立彙集索引的字段也須要惟一。

       結論:彙集索引能夠建立在任何一列你想建立的字段上,這是從理論上講,實際狀況並不能隨便指定,不然在性能上會是惡夢。

    第二:主鍵就是彙集索引

      這樣有時會對彙集索引的一種浪費。雖然SQL  SERVER默認是在主鍵上創建彙集索引的。可是因爲彙集索引的優點是很明顯的,而每一個表中只能有一個彙集索引的規則,這使得彙集索引變得更加珍貴。

      從咱們前面談到的彙集索引的定義咱們能夠看出,使用匯集索引的最大好處就是可以根據查詢要求,迅速縮小查詢範圍,避免全表掃描。在實際應用中,由於  ID號是自動生成的,咱們並不知道每條記錄的ID號,因此咱們很難在實踐中用ID號來進行查詢。這就使讓ID號這個主鍵做爲彙集索引成爲一種資源浪費。其次,讓每一個ID號都不一樣的字段做爲彙集索引也不符合「大數目的不一樣值狀況下不該創建聚合索引」規則;固然,這種狀況只是針對用戶常常修改記錄內容,特別是索引項的時候會負做用,但對於查詢速度並無影響。

    第三:是否是彙集索引就必定要比非彙集索引性能優呢? 

     若是想查詢學分在60-90之間的學生的學分以及姓名,在學分上建立彙集索引是不是最優的呢? 

     答:否。既然只輸出兩列,咱們能夠在學分以及學生姓名上建立聯合非彙集索引,此時的索引就造成了覆蓋索引,即索引所存儲的內容就是最終輸出的數據,這種索引在比以學分爲彙集索引作查詢性能更好。 

    第四:在數據庫中經過什麼描述彙集索引與非彙集索引的? 

     索引是經過二叉樹的形式進行描述的,咱們能夠這樣區分彙集與非彙集索引的區別:彙集索引的葉節點就是最終的數據節點,而非彙集索引的葉節仍然是索引節點,但它有一個指向最終數據的指針。 

    第五:在主鍵是建立彙集索引的表在數據插入上爲何比主鍵上建立非彙集索引錶速度要慢? 

     有了上面第四點的認識,咱們分析這個問題就有把握了,在有主鍵的表中插入數據行,因爲有主鍵惟一性的約束,因此須要保證插入的數據沒有重複。咱們來比較下主鍵爲彙集索引和非彙集索引的查找狀況:彙集索引因爲索引葉節點就是數據頁,因此若是想檢查主鍵的惟一性,須要遍歷全部數據節點才行,但非彙集索引不一樣,因爲非彙集索引上已經包含了主鍵值,因此查找主鍵惟一性,只須要遍歷全部的索引頁就行,這比遍歷全部數據行減小了很多IO消耗。這就是爲何主鍵上建立非彙集索引比主鍵上建立彙集索引在插入數據時要快的真正緣由。

相關文章
相關標籤/搜索