一分鐘掌握MySQL的InnoDB引擎B+樹索引

阿偉~發表於2020-05-17

MySQL的InnoDB索引結構採用B+樹,B+樹什麼概念呢,二叉樹大家都知道,我們都清楚隨著葉子結點的不斷增加,二叉樹的高度不斷增加,查詢某一個節點耗時就會增加,效能就會不斷降低,B+樹就是解決這個問題的。

B樹和B+樹

在一棵M階B樹中,每個節點最多有 M-1 個關鍵字,根節點最少可以只有一個關鍵字,非根節點最少有 Math.ceil(m/2)-1個關鍵字,下圖是一棵階數為3的樹

看下圖我們說說B樹的特點,很明顯一個節點儲存的資料更多了,不需要很高的高度就可以儲存更多的資料,把一個節點看作一個磁碟,我們發現查詢一個資料時可以減少磁碟IO次數,B樹的每個節點都有data域,

看下圖我們說說B+樹的特點,首先明確一點,B+樹是在B樹的基礎上演化而來的,我們就說不同點,只有葉子節點才有data域,葉子節點包含所有的資料,葉子節點通過指標連結形成雙向連結串列。

B/B+樹是為了磁碟或其它儲存裝置而設計的一種平衡多路查詢樹(相對於二叉,B樹每個內節點有多個分支),與紅黑樹相比,在相同的的節點的情況下,一顆B/B+樹的高度遠遠小於紅黑樹的高度(在下面B/B+樹的效能分析中會提到)。B/B+樹上操作的時間通常由存取磁碟的時間和CPU計算時間這兩部分構成,而CPU的速度非常快,所以B樹的操作效率取決於訪問磁碟的次數,關鍵字總數相同的情況下B樹的高度越小,磁碟I/O所花的時間越少

為什麼InnoDB選擇B+樹而不是B樹呢

還是上面兩張圖,對照著看,我們能夠得出一下結論

B+樹的磁碟讀取代價低, 樹每個節點都有data域,B+樹只有葉子節才有,假設每個節點大小16KB,那麼B+樹比B樹能儲存更多的關鍵字,一次性讀入記憶體的關鍵字的記憶體也會更多,B+樹的高度也會比B樹低,磁碟IO次數會更少。

B+樹對範圍查詢更友好,方便遍歷,B樹葉子節點沒有連結,而B+樹葉子節點通過雙向指標連結,可以很方便的進行範圍查詢,比如where條件中 age >=3 and age <20,,那麼當找到3時就可以順著指標找到20,而B樹是不可以的。

B+樹查詢效率穩定性更好, 在B+樹中,由於分支節點並不是最終指向檔案內容的節點,分支節點只是葉子節點的索引,所以對於任意關鍵字的查詢都必須從根節點走到分支節點,所有關鍵字查詢路徑長度相同,每個資料查詢效率相當。而對於B樹而言,其分支節點上也儲存有資料,對於每一個資料的查詢所走的路徑長度是不一樣的,效率也不一樣,B樹穩定性不如B+樹好

我們仔細想想我們SQL常見的查詢中,總結起來是不是也就是等於查詢, 範圍查詢

InnoDB非主鍵索引怎麼儲存呢?

我們上面介紹的只是主鍵索引是這樣儲存的,那麼非主鍵索引呢,其實非主鍵索引也B+樹的,只有非主鍵索引的葉子節點儲存的不是行記錄資料,而是主鍵值,通過主鍵值再次索引獲取所需要的資料。我畫一個粗略的見圖來表示

總結一下B+樹索引

採用了多叉樹的結構,降低了樹的高度,減少了磁碟IO次數,通過對所有葉子節點通過指標雙向連結,方便的提供了遍歷所有資料的特性,同時資料也是嚴格有序的,方便範圍查詢,查詢效率的穩定性也非常好。

相關文章