我們以MySQL為例,來說明btree索引算法和hash索引算法。首先,我們先了解一下索引,以及btree和hash是什么。
索引原理
索引用來快速尋找特定的數據值,如果沒有索引,查詢時需要遍歷整張表。原理大概是這樣:
- 把創建了索引的列內容排序
- 排序結果生成倒排表
- 在倒排表內容上拼上數據地址
- 在查詢時,先找到倒排表內容,再取出地址,最后找到數據
一、btree索引算法
- InnoDB存儲引擎默認的索引就是btree。
- 節點保存索引,而不是數據。所有的數據都保存在葉子節點,葉子節點不單保存數據,還包含指向數據指針,而且按照數據自小到大順序鏈接。(這里說的是b+tree)
- 數據的插入、刪除只在葉子節點進行。(這里說的是b+tree)
btree有兩種,一種是btree,還有一種是b+tree。數據庫中說的b+tree一般說的是b+tree。這兩種有什么區別呢?
- btree所有節點都是放索引和數據,而b+tree只在葉子節點放數據和索引,非葉子節點只存放索引。
- btree葉子節點相互獨立,b+tree葉子節點有一條鏈相連。
- btree可以實現把熱點數據放在離根節點進的節點,重復多次查詢熱數據更高效。
- b+tree,一次讀取,在內存頁獲取更多的索引,更快縮小范圍。
- 全局數據遍歷,b+tree只要找到最小節點,然后通過鏈進行順序遍歷。而btree需要每層遍歷。
二、hash索引算法
數據通過hash算法轉換成定長的哈希值,將哈希值與數據的行指針存入hash表中對應的位置,如果哈希值相同,在對應的hash中以鏈表形式存儲。這里的原理可以參考hashmap的put方法內部實現原理。
btree與hash區別:
- btree可以用作范圍查詢,比如>,>=,<,<=和between,除去通配符開頭查詢。而hash只能用作對等查詢。(這是因為使用hash建立的索引,它的順序與原順序無法保持一致。btree都是左節點<父節點<右節點。)
- hash一次定位數據,btree總是從根到葉子節點,所以hash檢索效率高。
- hash不支持使用索引排序。
- hash不支持模糊查詢以及最左前綴匹配。
- hash一定要回表查詢數據,btree的聚簇索引可以不用回表索引。
- hash等值查詢效率不一定比btree高。當哈希沖突很大,就會影響效率,而btree所有查詢都是從根到葉子節點。
基於這些情況,數據庫通常使用btree索引算法。
