天天看點

圖解Mysql索引的資料結構!看不懂你來找我

(一)關于索引

索引是幫助Mysql更加高效擷取資料的一種資料結構,索引的使用很簡單,但是如果不能了解索引底層的資料結構的話,就談不上去優化索引了。

(二)B+樹

Mysql的索引用的是B+樹,他具有這樣的幾個特點:

1、資料都存儲在葉子節點中、非葉子節點隻存儲索引

2、葉子節點中包含所有的索引

3、每個小節點的範圍都在大節點之間

4、葉子節點用指針相連,提高通路性能,比如條件是>或者<的查詢就可以直接按指針找(Mysql中的B+樹葉子節點中的指針是雙向指針)

圖解Mysql索引的資料結構!看不懂你來找我

B+樹的資料結構如圖所示,首先非葉子節點隻存儲索引,且每個指針所指向的節點最左邊的索引都是該指針對應的索引值,比如頭節點的第一個索引值8,指向的非葉子節點的第一個索引值也是8。

(三)為什麼索引這麼快?

索引可以支撐千萬級表的快速查找,為什麼呢?下面就來解釋一下:

show GLOBAL STATUS like 'Innodb_page_size'
           

在這裡插入圖檔描述

在Innodb中,預設的innodb_page_size大小為16kb,這就相當于上面每一個節點的大小預設情況下是16kb。一個索引值的大小為8B,索引後的指針所占大小為4B,是以可以解算出一個節點中大約可以存儲1170個索引。

對于葉子節點,由于存儲了資料,我們可以大方地估計每個資料的大小為1kb,相當于在葉子節點中每個節點可以存儲16個資料。

這樣就可以計算出一個三層的B+樹結構的索引一共可以存儲1170117016=2190萬條資料,這就意味着隻需要三次磁盤IO,就可以檢索兩千萬條資料,由此可見索引可以支撐千萬級表的快速查找。

(四)Innodb索引的實作

Mysql中的存儲引擎有Innodb和Myisam兩種,兩種索引的實作底層雖然都是B+樹,但是實作形式還是略有不同。

Innodb屬于聚簇索引,即葉子節點包含了完整的資料記錄。下面這張圖是innodb的主鍵索引,所有的資料都放在葉子節點中。

Innodb要求表必須有主鍵,并且推薦使用整型的自增主鍵,這也和他索引的實作有關,使用整型可以更好的進行B+樹的排序,同時采用自增的方式可以在插入資料時将資料插入到最後一個節點的後一個,而不用對已産生的索引拆分。

非主鍵索引和主鍵索引略有不通,非主鍵索引的葉子節點存儲的是主鍵的key值:

圖解Mysql索引的資料結構!看不懂你來找我

采用這種方式保持了資料的一緻性,當新增一條資料時,隻需要在主鍵索引處修改資料即可,而不會出現每個索引各自維護的情況。第二個優勢是節省了存儲的空間,資料隻需要儲存一份即可。

(五)MyIsam索引的實作

Myisam索引檔案和資料檔案是分離的,在MyIsam存儲引擎中,建立一張表後會在磁盤中增加三個檔案:

圖解Mysql索引的資料結構!看不懂你來找我

.frm 檔案存儲的是表結構,.MYI檔案存儲的是B+樹的索引表,MYD存儲的是資料,我通過下面這張表展示MyIsam索引:

(六)總結