1. 程式人生 > >MySQL聚集索引和非聚集索引

MySQL聚集索引和非聚集索引

高效 mar lock 包含 排列 查找 存儲 clust gin

索引分為聚集索引和非聚集索引,mysql中不同的存儲引擎對索引的底層實現可能會不同,這裏只關註mysql的默認存儲引擎InnoDB。
利用下面的命令可以查看默認的存儲引擎

show variables like ‘%storage_engine%‘;

聚集索引:

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

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

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

非聚集索引

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

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


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

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

總結如下:

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

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

MySQL聚集索引和非聚集索引