MySQL InnoDB索引的存儲結構

InnoDB索引的數據結構

InnoDB索引採用了B-Tree的數據結構,數據存儲在葉子節點上,每個葉子節點默認的大小是16KB。

當新記錄插入到InnoDB聚簇索引中時,如果按順序插入索引記錄(升序或降序),當達到葉子節點最大的容量時,下一條記錄就會寫到新的的頁中。葉子節點可使用的容量爲總容量的15/16,InnoDB會留1/16的空間,以備將來插入和更新索引記錄時使用, 如果以隨機順序插入記錄,則頁面的容量爲1/2到15/16之間。

你可以設置 innodb_page_size 來調整頁的大小,支持 64KB, 32KB, 16KB (默認), 8KB, 和4KB。

索引的分類

InnoDB的索引類型分爲主鍵索引和非主鍵索引

主鍵索引的葉子節點存的是整行數據。在 InnoDB 裏,主鍵索引也被稱爲聚簇索引(clustered index)。整張表的數據其實就是存儲在聚簇索引中的,聚簇索引就是表

如果沒有設置主鍵怎麼辦呢?MySQL會自動選擇一個可以唯一標識數據記錄的列作爲主鍵,如果不存在這種列,則MySQL自動爲InnoDB表生成一個隱含字段作爲主鍵。

聚簇索引結構如下圖所示:
在這裏插入圖片描述

非主鍵索引的葉子節點內容是主鍵的值。在 InnoDB 裏,非主鍵索引也被稱爲二級索引(secondary index)。二級索引的葉子節點中存的是主鍵的值,不是原始的數據,所以二級索引找到主鍵的值之後,需要用該主鍵再去主鍵索引上查找一次,才能獲取到最終的數據,這個過程叫做回表,這也是“二級”的含義。

二級索引結構如下圖所示:
在這裏插入圖片描述

創建索引的建議

由於二級索引中保存了主鍵值,所以索引主鍵值越小越好,以免二級索引佔用的空間過大,一般建議使用int的自增列作爲主鍵。這樣可以保證數據行是按順序寫入的,對於根據主鍵做關聯操作的性能也會更好。

因爲主鍵是順序的,所以每一條記錄都保存在上一條記錄的後面,當前的頁寫滿的時候,下一條記錄就寫在新的頁中。這樣在讀取數據的時候,就可以按順序讀取,充分利用了局部性的優勢,大大提高了讀取效率。

自增主鍵新增數據示例:
在這裏插入圖片描述

建議避免使用UUID作爲聚簇索引,它使得聚簇索引的插入變得完全隨機,使得數據沒有任何聚集特性。因爲UUID主鍵是隨機生成的,新的主鍵不一定比上一個主鍵大,所以無法每次都把新的主鍵插入到最後面,需要爲新的主鍵尋找合適的位置,通常在已有數據的中間位置。

在頁中間插入數據需要重新分配空間,以及移動旁邊的數據,這樣會導致頻繁的頁分裂操作同時會產生碎片。

UUID主鍵新增數據示例:
在這裏插入圖片描述
所以,聚簇索引最好用自增的列,並且要儘可能的小,這樣可以避免二級索引過大。











在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章