mysql 為啥用b+ 樹


原因就是為了減少磁盤io次數,因為b+樹所有最終的子節點都能在葉子節點里找見, 所以非葉子節點只需要存`索引范圍和指向下一級索引(或者葉子節點)的地址` 就行了, 不需要存整行的數據,所以占用空間非常小,直到找到葉子節點才加載進來整行的數據。 B樹非葉子節點也會存數據,所以不適合mysql(以后研究下mongo為啥用b樹 再補充) 

B+樹適合作為數據庫的基礎結構,完全是因為計算機的內存-機械硬盤兩層存儲結構。內存可以完成快速的隨機訪問(隨機訪問即給出任意一個地址,要求返回這個地址存儲的數據)但是容量較小。而硬盤的隨機訪問要經過機械動作(1磁頭移動 2盤片轉動),訪問效率比內存低幾個數量級,但是硬盤容量較大。典型的數據庫容量大大超過可用內存大小,這就決定了在B+樹中檢索一條數據很可能要借助幾次磁盤IO操作來完成。如下圖所示:通常向下讀取一個節點的動作可能會是一次磁盤IO操作,不過非葉節點通常會在初始階段載入內存以加快訪問速度。同時為提高在節點間橫向遍歷速度,真實數據庫中可能會將圖中藍色的CPU計算/內存讀取優化成二叉搜索樹(InnoDB中的page directory機制)。

 

 

image

真實數據庫中的B+樹應該是非常扁平的,可以通過向表中順序插入足夠數據的方式來驗證InnoDB中的B+樹到底有多扁平。我們通過如下圖的CREATE語句建立一個只有簡單字段的測試表,然后不斷添加數據來填充這個表。通過下圖的統計數據(來源見參考文獻1)可以分析出幾個直觀的結論,這幾個結論宏觀的展現了數據庫里B+樹的尺度。

1 每個葉子節點存儲了468行數據,每個非葉子節點存儲了大約1200個鍵值,這是一棵平衡的1200路搜索樹!

2 對於一個22.1G容量的表,也只需要高度為3的B+樹就能存儲了,這個容量大概能滿足很多應用的需要了。如果把高度增大到4,則B+樹的存儲容量立刻增大到25.9T之巨!

3 對於一個22.1G容量的表,B+樹的高度是3,如果要把非葉節點全部加載到內存也只需要少於18.8M的內存(如何得出的這個結論?因為對於高度為2的樹,1203個葉子節點也只需要18.8M空間,而22.1G從良表的高度是3,非葉節點1204個。同時我們假設葉子節點的尺寸是大於非葉節點的,因為葉子節點存儲了行數據而非葉節點只有鍵和少量數據。),只使用如此少的內存就可以保證只需要一次磁盤IO操作就檢索出所需的數據,效率是非常之高的。

image

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM