淺析MySQL InnoDB中的B+樹索引

首先列舉下在面試過程當中對於B+樹索引常見的兩個問題,但願經過本文簡要解決這些問題:mysql

  1. B+樹索引是什麼?
  2. 爲何說B+樹比B樹更適合數據庫索引?

B+樹索引介紹

B+tree

衆所周知,一顆傳統的M階B+樹須要知足如下幾個要求:面試

  • 從根節點到葉節點的全部路徑都具備相同的長度
  • 全部數據信息都存儲在葉子節點,非葉子節點僅做爲葉節點的索引存在
  • 根節點至少擁有兩個子樹
  • 每一個樹節點最多擁有M個子樹
  • 每一個樹節點(除了根節點)擁有至少M/2個子樹

B+樹是爲了磁盤及其餘存儲輔助設備而設計的一種平衡查找樹(不是二叉樹),在B+樹中,全部記錄的節點按大小順序存放在同一層的葉節點中,各葉子節點用指針進行鏈接,而B+樹索引本質上就是B+樹在數據庫中的實現,與純粹的B+樹數據結構仍是有點區別sql

B+樹與B+樹索引的區別以下:數據庫

B+樹 B+樹索引
存儲位置 內存 磁盤
扇出率
併發控制 能夠不考慮 需考慮
分裂方向 不須要考慮 向左、向右

一般來講,B+樹索引用於基於磁盤的數據庫系統,即數據最後持久化存放在磁盤上,每一個頁的葉子節點通常包含較多的記錄,所以具備較高的扇出。這意味着在數據庫中B+樹索引高度通常較小,在2~3層,其高度也決定了磁盤I/O搜索的次數數據結構

還有一點須要注意的是,實際上根據B+樹索引並不能找到一個給定值的具體行,B+樹索引能找到的只是查找數據行所在的頁。而後數據庫經過把數據頁讀入內存,再在內存中進行查找,最後獲得查找的數據。併發

爲何說B+樹比B樹更適合數據庫索引?

B+樹是上世紀70年代針對硬盤和單核處理器設計的,爲了減小機械硬盤的尋道次數,它採用了多叉樹結構,下降了索引結構的深度,IO讀寫次數減小。性能

熟悉數據結構的同窗都知道,B樹也是多叉樹結構,一種自平衡的樹,並且B+樹是從B樹演化而來的,那麼爲何不使用B+樹的前身B樹呢?一些資料也代表B樹也適用於讀寫相對大的數據塊的存儲系統,例如磁盤。下面來看下用B樹作索引的結構:.net

b tree

上圖小紅方塊表示文件內容在硬盤中的存儲位置。B樹相比B+樹的一個主要區別就在於B樹的分支節點上存儲着數據,而B+樹的分支節點只是葉子節點的索引而已。設計

從上面比較B+樹和B樹的結構,能夠得出爲何使用B+樹作索引的一些緣由(其實網上寫B+樹索引談到的大都是如下這些緣由):指針

1. B+樹的磁盤讀取代價低

B+-tree的內部節點並無指向關鍵字具體信息的指針,換句話說,即分支節點沒有存儲數據,所以其內部節點相對B 樹更小。若是把全部同一內部節點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀內存中的須要查找的關鍵字也就越多。相對來講IO讀寫次數也就下降了。

2. B+樹的查詢效率更加穩定

在B+樹中,因爲分支節點並非最終指向文件內容的節點,分支節點只是葉子節點的索引,因此對於任意關鍵字的查找都必須從根節點走到分支節點,全部關鍵字查詢路徑長度相同,每一個數據查詢效率至關。而對於B樹而言,其分支節點上也保存有數據,對於每個數據的查詢所走的路徑長度是不同的,效率也不同。

3. B+樹便於執行掃庫操做

因爲B+樹的數據都存儲在葉子節點上,分支節點均爲索引,方便掃庫,只需掃一遍葉子便可。可是B樹在分支節點上都保存着數據,要找到具體的順序數據,須要執行一次中序遍從來查找。因此B+樹更加適合範圍查詢的狀況,在解決磁盤IO性能的同時解決了B樹元素遍歷效率低下的問題

小結

再次總結下B+樹索引,它採用了多叉樹的結構,下降了索引結構的深度,避免了傳統二叉樹結構中絕大部分的隨機訪問操做,有效減小了磁盤磁頭的尋道次數。B+樹索引查詢效率穩定,也有利於進行範圍查詢。

參考資料 & 鳴謝

相關文章
相關標籤/搜索