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值大小并不必定一致。数据结构

相关文章
相关标签/搜索