1. 程式人生 > >《MySQL實戰45講》學習筆記3——InnoDB為什麼採用B+樹結構實現索引

《MySQL實戰45講》學習筆記3——InnoDB為什麼採用B+樹結構實現索引

索引的作用是提高查詢效率,其實現方式有很多種,常見的索引模型有雜湊表、有序列表、搜尋樹等。

雜湊表

  • 一種以key-value鍵值對的方式儲存資料的結構,通過指定的key可以找到對應的value。
  • 雜湊把值放在數組裡,用一個雜湊函式把key換算成一個確定位置,然後把value放在陣列的這個位置。但是,多個key值經過雜湊函式的換算,可能會出現同一個值,即雜湊衝突,常見的解決辦法是鏈地址法,即將所有的相同Hash值的key放在一個連結串列中,這樣,無論有多少個衝突,都只是在當前位置給單鏈表增加節點。
  • 適用於只有等值查詢的場景,區間查詢會很慢。

有序列表

  • 支援等值查詢和範圍查詢,但是更新資料的成本比較高。
  • 適用於靜態儲存索引,比如儲存的是2017年某個城市人口資訊這類不會修改的資料。

1.二叉樹:
  • 每個節點的左兒子小於父節點,父節點小於右兒子。
  • 查詢、更新某個節點的時間複雜度都是O(log(N)),搜尋效率最高。
2.B樹(多叉樹):

根節點至少有兩個子節點,每個節點的子節點間,其大小都是從左到右遞增。

3.B+樹:
  • B+樹的葉子節點儲存了父節點的所有鍵值和鍵值對應的資料,每個葉子節點的鍵值從小到大連結,但非葉子節點不儲存鍵值對應的資料,這樣使得B+樹每個節點所能儲存的鍵值大大增加;
  • 由於B+樹的非葉子節點只進行資料索引,不會存實際的鍵值對應的資料,所有的資料必須到葉子節點才能獲取到,所以每次資料查詢的次數都一樣。

因為索引不止存在記憶體中,還要寫在磁碟上,為了儘量少地讀寫磁碟,減少IO次數,所以儘管二叉樹的效率很高,大多數資料庫不會選擇二叉樹。

可以想象一下一棵 100 萬節點的平衡二叉樹,樹高 20。一次查詢可能需要訪問 20 個數據塊。在機械硬碟時代,從磁碟隨機讀一個數據塊需要 10 ms 左右的定址時間。也就是說,對於一個 100 萬行的表,如果使用二叉樹來儲存,單獨訪問一個行可能需要 20 個 10 ms 的時間。

InnoDB使用B+樹索引模型,所有資料都儲存在B+樹中,每一個索引對應一棵B+樹。

以 InnoDB 的一個整數字段索引為例,這個 N 差不多是 1200。這棵樹高是 4 的時候,就可以存 1200 的 3 次方個值,這已經 17 億了。考慮到樹根的資料塊總是在記憶體中的,一個 10 億行的表上一個整數字段的索引,查詢一個值最多隻需要訪問 3 次磁碟。其實,樹的第二層也有很大概率在記憶體中,那麼訪問磁碟的平均次數就更少了。

結論:InnoDB採用B+樹結構,是因為B+樹能夠很好地配合磁碟的讀寫特性,減少單次查詢的磁碟訪問次數,降低IO、提升效能