B+樹索引和哈希索引的區別

yzqyzq11 8年前發布 | 11K 次閱讀 哈希表 MySQL 數據庫服務器

來自: http://ourmysql.com/archives/1417

導讀

在MySQL里常用的索引數據結構有B+樹索引和哈希索引兩種,我們來看下這兩種索引數據結構的區別及其不同的應用建議。

</div>

二者區別

備注:先說下, 在MySQL文檔里,實際上是把B+樹索引寫成了BTREE ,例如像下面這樣的寫法:

CREATE TABLE t(

aid int unsigned not null auto_increment,

userid int unsigned not null default 0,

username varchar(20) not null default ‘’,

detail varchar(255) not null default ‘’,

primary key(aid),

unique key(uid) USING BTREE ,

key (username(12)) USING BTREE此處 uname 列只創建了最左12個字符長度的部分索引

)engine=InnoDB;

</div>

一個經典的 B+樹索引數據結構 見下圖:

(圖片源自網絡)

B+樹是一個平衡的多叉樹,從根節點到每個葉子節點的高度差值不超過1,而且同層級的節點間有指針相互鏈接。

在B+樹上的常規檢索,從根節點到葉子節點的搜索效率基本相當,不會出現大幅波動,而且基于索引的順序掃描時,也可以利用雙向指針快速左右移動,效率非常高。

因此,B+樹索引被廣泛應用于數據庫、文件系統等場景。順便說一下,xfs文件系統比ext3/ext4效率高很多的原因之一就是,它的文件及目錄索引結構全部采用B+樹索引,而ext3/ext4的文件目錄結構則采用Linked list, hashed B-tree、Extents/Bitmap等索引數據結構,因此在高I/O壓力下,其IOPS能力不如xfs。

詳細可參見:

https://en.wikipedia.org/wiki/Ext4https://en.wikipedia.org/wiki/XFS

哈希索引的示意圖 則是這樣的:

(圖片源自網絡)

簡單地說, 哈希索引就是采用一定的哈希算法 ,把鍵值換算成新的哈希值,檢索時不需要類似B+樹那樣從根節點到葉子節點逐級查找,只需一次哈希算法即可立刻定位到相應的位置,速度非常快。

從上面的圖來看,B+樹索引和哈希索引的明顯區別是:

  • 如果是等值查詢,那么哈希索引明顯有絕對優勢,因為只需要經過一次算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然后再根據鏈表往后掃描,直到找到相應的數據;

  • 從示意圖中也能看到, 如果是范圍查詢檢索,這時候哈希索引就毫無用武之地了 ,因為原先是有序的鍵值,經過哈希算法后,有可能變成不連續的了,就沒辦法再利用索引完成范圍查詢檢索;

  • 同理, 哈希索引也沒辦法利用索引完成排序 ,以及like ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質上也是范圍查詢);

  • 哈希索引也不支持多列聯合索引的最左匹配規則;

  • B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大, 在有大量重復鍵值情況下,哈希索引的效率也是極低的,因為存在所謂的哈希碰撞問題 。

后記

在MySQL中,只有HEAP/MEMORY引擎表才能顯式支持哈希索引(NDB也支持,但這個不常用),InnoDB引擎的自適應哈希索引(adaptive hash index)不在此列,因為這不是創建索引時可指定的。

還需要注意到:HEAP/MEMORY引擎表在mysql實例重啟后,數據會丟失。

通常,B+樹索引結構適用于絕大多數場景,像下面這種場景用哈希索引才更有優勢:

在HEAP表中,如果存儲的數據重復度很低(也就是說基數很大),對該列數據以等值查詢為主,沒有范圍查詢、沒有排序的時候,特別適合采用哈希索引

例如這種SQL:SELECT … FROM t WHERE C1 = ?; — 僅等值查詢

在大多數場景下,都會有范圍查詢、排序、分組等查詢特征,用B+樹索引就可以了。

</div>

 本文由用戶 yzqyzq11 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!