MySQL索引結構採用B+樹的緣由

今天看了好多關於MySQL索引的文章,對MySQL的索引結構採用B+樹的緣由進行梳理。html

首先來回顧一下數據結構課程中學過的一些樹的結構。數據庫

1、二叉查找樹

1.1 性質

  • 任意節點左子樹不爲空,則左子樹的值均小於根節點的值;
  • 任意節點右子樹不爲空,則右子樹的值均大於於根節點的值;
  • 任意節點的左右子樹也分別是二叉查找樹;
  • 沒有鍵值相等的節點; 

上圖爲一個普通的二叉查找樹,按照中序遍歷的方式能夠從小到大的順序排序輸出:二、三、五、六、七、8。數據結構

對上述二叉樹進行查找,如查鍵值爲5的記錄,先找到根,其鍵值是6,6大於5,所以查找6的左子樹,找到3;而5大於3,再找其右子樹;一共找了3次。若是按二、三、五、六、七、8的順序來找一樣需求3次。用一樣的方法在查找鍵值爲8的這個記錄,此次用了3次查找,而順序查找須要6次。計算平均查找次數得:順序查找的平均查找次數爲(1+2+3+4+5+6)/ 6 = 3.3次,二叉查找樹的平均查找次數爲(3+3+3+2+2+1)/6=2.3次。二叉查找樹的平均查找速度比順序查找來得更快。性能

1.2 侷限性

一個二叉查找樹是由n個節點隨機構成,因此,對於某些狀況,二叉查找樹會退化成一個有n個節點的線性鏈。若是咱們的根節點選擇是最小或者最大的數,那麼二叉查找樹就徹底退化成了線性結構。顯然這個二叉樹的查詢效率就很低,所以若想最大性能的構造一個二叉查找樹,須要這個二叉樹是平衡的(這裏的平衡從一個顯著的特色能夠看出這一棵樹的高度比上一個輸的高度要大,在相同節點的狀況下也就是不平衡),從而引出了一個新的定義-平衡二叉樹AVL。spa

2、AVL樹(平衡的二叉查找樹)

2.1 特性

AVL樹是帶有平衡條件的二叉查找樹,通常是用平衡因子差值判斷是否平衡並經過旋轉來實現平衡,左右子樹高度差不超過1,和紅黑樹相比,它是嚴格的平衡二叉樹,平衡條件必須知足(全部節點的左右子樹高度差不超過1)。無論咱們是執行插入仍是刪除操做,只要不知足上面的條件,就要經過旋轉來保持平衡,而旋轉是很是耗時的,由此咱們能夠知道AVL樹適合用於插入刪除次數比較少,但查找多的狀況。 .net

2.2 侷限性

因爲維護這種高度平衡所付出的代價比從中得到的效率收益還大,故而實際的應用很少,更多的地方是用追求局部而不是很是嚴格總體平衡的紅黑樹。固然,若是應用場景中對插入刪除不頻繁,只是對查找要求較高,那麼AVL仍是較優於紅黑樹。設計

3、紅黑樹

關於紅黑樹,具體能夠看我另外一篇博客:https://my.oschina.net/edwardge/blog/18338933d

因爲紅黑樹本質上仍是二叉樹,高度仍是過高,做爲索引的數據結構並不合適。htm

4、B樹/B+樹

咱們知道MySQL的數據是存放在磁盤上的,而讀取磁盤的IO開銷很是大,當須要定位到磁盤的具體位置時就須要幾回IO操做,因此每次進行查找時就要想辦法儘可能控制對磁盤的IO操做次數,而B+樹的結構正好知足。B/B+樹是爲了磁盤或其它存儲設備而設計的一種平衡多路查找樹(相對於二叉,B樹每一個內節點有多個分支),與紅黑樹相比,在相同的的節點的狀況下,一顆B/B+樹的高度遠遠小於紅黑樹的高度(在下面B/B+樹的性能分析中會提到)。B/B+樹上操做的時間一般由存取磁盤的時間和CPU計算時間這兩部分構成,而CPU的速度很是快,因此B樹的操做效率取決於訪問磁盤的次數,關鍵字總數相同的狀況下B樹的高度越小,磁盤I/O所花的時間越少。blog

那麼爲何採用B+樹而不是B樹呢?

咱們先來看二者結構上的區別:

  • B+樹的磁盤讀寫代價更低,由於B+樹的全部非葉子節點只會存放索引信息,而真正的數據信息都只存放在葉子節點中,這樣一來,每一個非葉子節點存放的索引信息就更多,一次磁盤IO就能夠讀取更多的索引信息到內存中,能夠減小磁盤IO的次數。
  • B+樹的查詢效率更加穩定,因爲非葉子節點只存索引信息,而沒有真正的數據信息,因此任何關鍵字的查找必須走一條從根結點到葉子結點的路。全部關鍵字查詢的路徑長度相同,致使每個數據的查詢效率至關。
  • B+樹更加適合在區間查詢的狀況,因爲B+樹的數據都存儲在葉子結點中,非葉子結點均爲索引,只須要掃一遍葉子結點便可獲得全部數據信息,可是B樹由於其非葉子結點一樣存儲着數據,咱們要找到具體的數據,須要進行一次中序遍歷按序來掃,因此B+樹更加適合在區間查詢的狀況,因此一般B+樹用於數據庫索引。

部份內容參考如下博客:

https://www.jianshu.com/p/4dbbaaa200c4

http://www.javashuo.com/article/p-nlfpbsij-k.html

相關文章
相關標籤/搜索