聚簇索引與非聚簇索引的區別

一般狀況下,創建索引是加快查詢速度的有效手段。但索引不是萬能的,靠索 引並不能實現對全部數據的快速存取。事實上,若是索引策略和數據檢索需求嚴重不符的話,創建索引反而會下降查詢性能。所以在實際使用當中,應該充分考慮到 索引的開銷,包括磁盤空間的開銷及處理開銷(如資源競爭和加鎖)。例如,若是數據頻繁的更新或刪加,就不宜創建索引。算法

    本文 簡要討論一下聚簇索引的特色及其與非聚簇索引的區別。
  • 創建索引:
在SQL語言中,創建聚簇索引使用CREATE INDEX語句,格式爲:CREATE CLUSTER INDEX index_name ON table_name(column_name1,column_name2,...);
  • 存儲特色:
  1. 彙集索引。表數據按照索引的順序來存儲的,也就是說索引項的順序與表中記錄的物理順序一致。對於彙集索引,葉子結點即存儲了真實的數據行,再也不有另外單獨的數據頁。 在一張表上最多隻能建立一個彙集索引,由於真實數據的物理順序只能有一種。
  2. 非彙集索引。表數據存儲順序與索引順序無關。對於非彙集索引,葉結點包含索引字段值及指向數據頁數據行的邏輯指針,其行數量與數據錶行數據量一致。
    總結一下:彙集索引是一種稀疏索引,數據頁上一級的索引頁存儲的是頁指針,而不是行指針。而對於非彙集索引,則是密集索引,在數據頁的上一級索引頁它爲每個數據行存儲一條索引記錄。
  • 更新表數據
一、向表中插入新數據行
    若是一張表沒有彙集索引,那麼它被稱爲「堆集」(Heap)。這樣的表中的數據行沒有特定的順序,全部的新行將被添加到表的末尾位置。而創建了聚簇索引的數據表則不一樣:最簡單的狀況下,插入操做根據索引找到對應的數據頁,而後經過挪動已有的記錄爲新數據騰出空間,最後插入數據。若是數據頁已滿,則須要拆分數據頁,調整索引指針(且若是表還有非彙集索引,還須要更新這些索引指向新的數據頁)。而相似於自增列爲彙集索引的,數據庫系統可能並不拆分數據頁,而只是簡單的新添數據頁。

二、從表中刪除數據行數據庫

    對刪除數據行來講:刪除行將致使其下方的數據行向上移動以填充刪除記錄形成的空白。若是刪除的行是該數據頁中的最後一行,那麼該數據頁將被回收,相應的索 引頁中的記錄將被刪除。對於數據的刪除操做,可能致使索引頁中僅有一條記錄,這時,該記錄可能會被移至鄰近的索引頁中,原索引頁將被回收,即所謂的「索引 合併」。ide

 

 

 

聚簇索引肯定表中數據的物理順序。聚簇索引相似於電話簿,後者按姓氏排列數據。因爲聚簇索引規定數據在表中的物理存 儲順序,所以一個表只能包含一個聚簇索引。但該索引能夠包含多個列(組合索引),就像電話簿按姓氏和名字進行組織同樣。漢語字典也是聚簇索引的典型應用, 在漢語字典裏,索引項是字母+聲調,字典正文也是按照先字母再聲調的順序排列。

 

聚簇索引對於那些常常要搜索範圍值的列特別有效。使用聚簇索引找到包含第一個值的行後,即可以確保包含後續索引值的行在物理相鄰。例如,若是應用程序執行的一個查詢常常檢索某一日期範圍內的記錄,則使用 彙集索引能夠迅速找到包含開始日期的行,而後檢索表中全部相鄰的行,直到到達結束日期。這樣有助於提升此類查詢的性能。一樣,若是對從表中檢索的數據進行排序時常常要用到某一列,則能夠將該表在該列上聚簇(物理排序),避免每次查詢該列時都進行排序,從而節省成本。
 

創建聚簇索引的思想

一、大多數表都應該有聚簇索引或使用分區來下降對錶尾頁的競爭,在一個高 事務的環境中,對最後一頁的封鎖嚴重影響系統的吞吐量。
二、在聚簇索引下,數據在物理上按順序排在數據頁上,重複值也排在一塊兒,於是在那些包含範圍檢查 (between、<、<=、>、>=)或使用group by或orderby的查詢時,一旦找到具備範圍中第一個鍵值的行,具備後續索引值的行保證物理上毗連在一塊兒而沒必要進一步搜索,避免了大範圍掃描,能夠大 大提升查詢速度。
三、在一個頻繁發生插入操做的表上創建聚簇索引時,不要建在具備單調上升值的列(如IDENTITY)上,不然會常常引發封鎖衝突。
四、在聚簇索引中不要包含常常修改的列,由於碼值修改後,數據行必須移動到新的位置。
五、選擇聚簇索引應基於where子句和鏈接操做的類型。
 
不知從什麼角度來對比,只能說說各自的特色,但願對你有用。
一、聚簇索引
a) 一個索引項直接對應實際數據記錄的存儲頁,可謂「直達」
b) 主鍵缺省使用它
c) 索引項的排序和數據行的存儲排序徹底一致,利用這一點,想修改數據的存儲順序,能夠經過改變主鍵的方法(撤銷原有主鍵,另找也能知足主鍵要求的一個字段或一組字段,重建主鍵)
d) 一個表只能有一個聚簇索引(理由:數據一旦存儲,順序只能有一種)

二、非聚簇索引
a) 不能「直達」,可能鏈式地訪問多級頁表後,才能定位到數據頁
b) 一個表能夠有多個非聚簇索引





第二種理解:

聚簇索引是對磁盤上實際數據從新組織以按指定的一個或多個列的值排序的算法。特色是存儲數據的順序和索引順序一致。
通常狀況下主鍵會默認建立聚簇索引,且一張表只容許存在一個聚簇索引。佈局

在《數據庫原理》一書中是這麼解釋聚簇索引和非聚簇索引的區別的:
聚簇索引的葉子節點就是數據節點,而非聚簇索引的葉子節點仍然是索引節點,只不過有指向對應數據塊的指針。性能

所以,MYSQL中不一樣的數據存儲引擎對聚簇索引的支持不一樣就很好解釋了。
下面,咱們能夠看一下MYSQL中MYISAM和INNODB兩種引擎的索引結構。spa

如原始數據爲:

MyISAM引擎的數據存儲方式如圖:

指針

MYISAM是按列值與行號來組織索引的。它的葉子節點中保存的其實是指向存放數據的物理塊的指針。
從MYISAM存儲的物理文件咱們能看出,MYISAM引擎的索引文件(.MYI)和數據文件(.MYD)是相互獨立的。orm

而InnoDB按聚簇索引的形式存儲數據,因此它的數據佈局有着很大的不一樣。它存儲數據的結構大體以下:

注:聚簇索引中的每一個葉子節點包含主鍵值、事務ID、回滾指針(rollback pointer用於事務和MVCC)和餘下的列(如col2)。htm

INNODB的二級索引與主鍵索引有很大的不一樣。InnoDB的二級索引的葉子包含主鍵值,而不是行指針(row pointers),這減少了移動數據或者數據頁面分裂時維護二級索引的開銷,由於InnoDB不須要更新索引的行指針。其結構大體以下:

排序

INNODB和MYISAM的主鍵索引與二級索引的對比:

InnoDB的的二級索引的葉子節點存放的是KEY字段加主鍵值。所以,經過二級索引查詢首先查到是主鍵值,而後InnoDB再根據查到的主鍵值經過主鍵
索引找到相應的數據塊。而MyISAM的二級索引葉子節點存放的仍是列值與行號的組合,葉子節點中保存的是數據的物理地址。因此能夠看出MYISAM的主
鍵索引和二級索引沒有任何區別,主鍵索引僅僅只是一個叫作PRIMARY的惟1、非空的索引,且MYISAM引擎中能夠不設主鍵
相關文章
相關標籤/搜索