8 mysql Hash索引和BTree索引區別

Hash僅支持=、>、>=、<、<=、between。BTree可以支持like模糊查詢

索引是幫助mysql獲取數據的數據結構。最常見的索引是Btree索引和Hash索引。

不同的引擎對於索引有不同的支持:Innodb和MyISAM默認的索引是Btree索引;而Mermory默認的索引是Hash索引。

我們在mysql中常用兩種索引算法BTree和Hash,兩種算法檢索方式不一樣,對查詢的作用也不一樣。
一、BTree
BTree索引是最常用的mysql數據庫索引算法,因爲它不僅可以被用在=,>,>=,<,<=和between這些比較操作符上,而且還可以用於like操作符,只要它的查詢條件是一個不以通配符開頭的常量,例如:
select * from user where name like ‘jack%’;
select * from user where name like ‘jac%k%’;
如果一通配符開頭,或者沒有使用常量,則不會使用索引,例如:
select * from user where name like ‘%jack’;
select * from user where name like simply_name;
二、Hash
Hash索引只能用於對等比較,例如=,<=>(相當於=)操作符。由於是一次定位數據,不像BTree索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次IO訪問,所以檢索效率遠高於BTree索引。
但爲什麼我們使用BTree比使用Hash多呢?主要Hash本身由於其特殊性,也帶來了很多限制和弊端:

  1. Hash索引僅僅能滿足“=”,“IN”,“<=>”查詢,不能使用範圍查詢。
  2. 聯合索引中,Hash索引不能利用部分索引鍵查詢。
    對於聯合索引中的多個列,Hash是要麼全部使用,要麼全部不使用,並不支持BTree支持的聯合索引的最優前綴,也就是聯合索引的前面一個或幾個索引鍵進行查詢時,Hash索引無法被利用。
  3. Hash索引無法避免數據的排序操作
    由於Hash索引中存放的是經過Hash計算之後的Hash值,而且Hash值的大小關係並不一定和Hash運算前的鍵值完全一樣,所以數據庫無法利用索引的數據來避免任何排序運算。
  4. Hash索引任何時候都不能避免表掃描
    Hash索引是將索引鍵通過Hash運算之後,將Hash運算結果的Hash值和所對應的行指針信息存放於一個Hash表中,由於不同索引鍵存在相同Hash值,所以即使滿足某個Hash鍵值的數據的記錄條數,也無法從Hash索引中直接完成查詢,還是要通過訪問表中的實際數據進行比較,並得到相應的結果。
  5. Hash索引遇到大量Hash值相等的情況後性能並不一定會比BTree高
    對於選擇性比較低的索引鍵,如果創建Hash索引,那麼將會存在大量記錄指針信息存於同一個Hash值相關聯。這樣要定位某一條記錄時就會非常麻煩,會浪費多次表數據訪問,而造成整體性能底下。

1. hash索引查找數據基本上能一次定位數據,當然有大量碰撞的話性能也會下降。而btree索引就得在節點上挨着查找了,很明顯在數據精確查找方面hash索引的效率是要高於btree的;
2. 那麼不精確查找呢,也很明顯,因爲hash算法是基於等值計算的,所以對於“like”等範圍查找hash索引無效,不支持;
3. 對於btree支持的[聯合索引]的最優前綴,hash也是無法支持的,[聯合索引]中的字段要麼全用要麼全不用。提起最優前綴居然都泛起迷糊了,看來有時候放空得太厲害;
4. hash不支持索引排序,索引值和計算出來的hash值大小並不一定一致。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章