mysql 聚集索引,非聚集索引,覆蓋索引區別

索引分為聚集索引和非聚集索引,mysql中不同的存儲引擎對索引的底層實現可能會不同,這裡只關注mysql的默認存儲引擎InnoDB

聚集索引:

索引中鍵值的邏輯順序決定了表中相應行的物理順序(索引中的數據物理存放地址和索引的順序是一致的),可以這麼理解:只要是索引是連續的,那麼數據在存儲介質上的存儲位置也是連續的。
比方說:想要到字典上查找一個字,我們可以根據字典前面的拼音找到該字,注意拼音的排列時有順序的。

打個比方:當我們想要找“啊”這個字,然後又想找“不”這個字,根據拼音來看“b”一定在”a“的後面。

聚集索引就像我們根據拼音的順序查字典一樣,可以大大的提高效率。在經常搜索一定範圍的值時,通過索引找到第一條數據,根據物理地址連續存儲的特點,然後檢索相鄰的數據,直到到達條件截至項。

非聚集索引

索引的邏輯順序與磁盤上的物理存儲順序不同

。非聚集索引的鍵值在邏輯上也是連續的,但是表中的數據在存儲介質上的物理順序是不一致的,即記錄的邏輯順序和實際存儲的物理順序沒有任何聯繫。索引的記錄節點有一個數據指針指向真正的數據存儲位置。

非聚集索引就像根據偏旁部首查字典一樣,字典前面的目錄在邏輯上也是連續的,但是查兩個偏旁在目錄上挨著的字時,字典中的字卻很不可能是挨著的。

下面是MySQL文檔中關於索引的說明:

每個InnoDB表有一個特殊的指數稱為聚集索引所在的行的數據存儲。通常,聚集索引是主鍵的同義詞。從查詢,插入性能最好,和其他的數據庫操作,必須瞭解InnoDB使用聚集索引來優化每個表最常見的查詢和DML操作。
當你定義你的表的主鍵,InnoDB使用它作為聚集索引。為您創建的每個表定義一個主鍵。如果沒有邏輯唯一的和非空的列或列集,添加一個新的自動增量列,它的值自動填充。
如果你不確定你的表的主鍵、唯一索引,MySQL定位第一所有鍵列不為空,InnoDB使用它作為聚集索引。
如果表沒有主鍵或唯一索引InnoDB內部適用,生成一個隱藏的聚集索引為合成列包含行ID值gen_clust_index。行的ID,InnoDB分配在這樣一個表中的行排序。行ID是一個6字節字段的單調增加,在插入新行。因此,行id命令的行在物理上是插入順序。

覆蓋索引:

如果一個索引包含所有需要查詢的字段的值,我們就稱之為“覆蓋索引”。因此不需要通過主鍵ID值的查找數據行的真實所在, 直接取得葉節點中name的值返回即可。

總結如下:

  • 如果一個主鍵被定義了,那麼這個主鍵就是作為聚集索引
  • 如果沒有主鍵被定義,那麼該表的第一個唯一非空索引被作為聚集索引
  • 如果沒有主鍵也沒有合適的唯一索引,那麼innodb內部會生成一個隱藏的主鍵作為聚集索引,這個隱藏的主鍵是一個6個字節的列,改列的值會隨著數據的插入自增。

InnoDB引擎會為每張表都加一個聚集索引,而聚集索引指向的的數據又是以物理磁盤順序來存儲的,自增的主鍵會把數據自動向後插入,避免了插入過程中的聚集索引排序問題。如果對聚集索引進行排序,這會帶來磁盤IO性能損耗是非常大的。


分享到:


相關文章: