mysql Hash索引和BTree索引區別

Hash僅支持=、>、>=、<、<=、between。BTree能夠支持like模糊查詢mysql

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

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

咱們在mysql中經常使用兩種索引算法BTree和Hash,兩種算法檢索方式不同,對查詢的做用也不同。
1、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;
2、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值大小並不必定一致。數據結構

相關文章
相關標籤/搜索