MySql 索引之 B 樹與 B+ 樹


上一片文章我們講過了,B 樹索引是 MySql 常用引擎(InnoDB,MyISAM)的索引。

提出問題

什么是 B 樹,它有什么特性那?B+ 樹與 B 樹有什么區別?我們平常用的二叉搜索樹的時間復雜度不是 LogN 嗎?難道不夠優秀嗎?

解決問題

預備知識

磁盤 IO:系統讀取磁盤是將磁盤的基本單位---磁盤塊讀取出來。磁盤讀取 IO 是機械動作,時間大概為內存讀取的十多萬倍。所以磁盤 IO 讀寫速度稱為索引性能的主要指標

二叉搜索樹

二叉搜索樹(Binary Search Tree,BST),它的時間復雜度為 LogN。

在二叉搜索樹中,我們要執行搜索,最好情況是搜索 0009,也就是 BST 的根結點,只需要一次磁盤 IO。最壞情況就是樹最深的底層葉子節點(深度為 N 就需要 N 次磁盤 IO)。

二叉搜索樹已經很優秀了,還有沒有優化的空間?我們從以下幾個點來考慮。

  1. BST 的最壞情況怎么優化。
  2. 二叉搜索樹是由樹的深度決定的,我們能不能壓縮它。
B 樹

B 樹,平衡多路查找樹。B 樹是為磁盤等存儲設備設計的一種平衡查找樹。B 樹結構的數據可以讓系統高效的找到數據所在的磁盤塊。

我們以主鍵索引為例子。

上圖就是一個 B 樹,紫色為 Key,黃色為 data,藍色為指針。

相比於之前的 BST 多了在每一個磁盤頁的索引比較,但是因為磁盤頁已經被磁盤 IO 操作讀取到了內存中。因為內存 IO 操作比磁盤 IO 操作省時很多根本不在一個數量級所以可以忽略不計,所以磁盤 IO 操作仍然是最重要的性能指標。

B 樹相比於二叉搜索樹壓縮了深度,所以磁盤 IO 會比二叉搜索樹少,能有效地提高新能,所以 B 樹更適合索引。

B+ 樹

B+ 樹是在 B 樹的基礎上的一種優化,使其更適合實現外存儲索引結構。InnoDB 和 MyISAM 存儲引擎都是使用 B+ 樹實現其索引結構。

我們說過,B 樹的索引和關鍵自 key-data 存儲在磁盤里面,然后被磁盤 IO 操作讀入內存。如果這個 data 很大的話,每次家在到內存中的 key 就會減少,這會使得 B 樹的深度增加,這樣還是會增加磁盤 IO 查詢。

為了解決這個問題,B+ 樹將所有數據記錄節點按照鍵值的大小順序存放在同一層葉子節點上,而非葉子節點只存儲 key 值信息,這樣可以大大增加每個節點存儲的 key 值的數量,降低 B+ 樹的高度。

非葉子節點只存儲鍵值信息,所有葉子節點之間都有一個鏈指針,數據記錄都存儲於葉子節點中

B 樹與 B+ 樹的區別
  1. B+ 樹的磁盤讀寫更低,因為非葉子節點可以存儲更多的索引 key,而 key 索引在同一層更集中,那么會降低磁盤 IO 讀寫次數。
  2. B+ 樹的查詢效率更穩定,任何查詢都必須從根節點到葉子節點,路徑是相似的,所以更穩定(最好最壞都在底層)。
  3. 區間訪問友好性,MySQL 是關系型數據庫,所以經常會按照區間來訪問某個索引,B+ 樹的葉子節點會按照順序建立起鏈狀指針,增強了區間訪問性。

MySQL 為什么使用 B/B+ 樹來實現索引那?

MySQL 是基於磁盤的數據庫,索引是以索引文件的形式存於磁盤中的。索引的過程就是磁盤 IO 的過程,磁盤 IO 消耗比內存 IO 消耗好幾個數量級,所以能有效減少磁盤 IO 的數據結構適合用來實現數據庫索引。


免責聲明!

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



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