B+tree索引

B+tree索引的特点,请看上一篇博客

Hash索引

Hash索引是根据Hash结构的定义,只需要一次运算便可以找到数据所在位置,不像B+树或者B树需要从根结点出发寻找数据,所以Hash索引的查询效率理论上要高于B+树索引,但是MySQL中并没有采用这一种索引,这是由于这种索引除查询效率之外的缺陷是十分明显的。
MySQL索引系列:Btree索引和hash索引

Hash索引的特点:

  1. Hash索引包括键值、Hash码和指针;对于Hash索引中的所有列,存储引擎都会为每一行计算一个Hash码,Hash索引中存储的就是Hash码。

  2. Hash索引必须进行二次查找使用哈希索引两次查找,第一次找到相应的行,第二次读取数据,但是被频繁访问到的行一般会缓存在内存中,这点对数据库性能的影响不大。

  3. Hash索引是基于Hash表实现的,仅仅只能满足"=","IN"等精确匹配,不能使用范围查询。例如 WHERE price > 100。由于Hash索引比较的是进行Hash运算之后的Hash值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的Hash算法处理之后的Hash值的大小关系,并不能保证和Hash运算前完全一样。

  4. 无法被用来数据的排序操作,Hash索引存储的是hash码而不是键值,所以无法用于外排序。

  5. Hash索引不支持部分索引查找、也不支持范围查找和模糊查询。

    对于组合索引,Hash索引在计算Hash值的时候是组合索引键合并后再一起计算Hash值,而不是单独计算Hash值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash索引也无法被利用。

  6. 不能避免全表扫描。由于Hash索引中的Hash码的计算会产生Hash冲突,存在Hash冲突的数据会被连接到同一个链表上。当大量数据被连接到相同链表上时,查询某条数据时,存储引擎必须遍历整个链表中的所有行指针,逐行比较,直到找到所有的符合条件的行。此时时间复杂度并不能保证在O(1),性能也并不一定就会比B-Tree索引高。所以说Hash索引不适用于重复值很多的列上。

为什么 MySQL 索引选择了 B+树而不是 B 树?

  • B+树更适合外部存储(一般指磁盘存储),由于内节点(非叶子节点)不存储 data,所以一个节点可以存储更多的内节点,每个节点能索引的范围更大更精确。也就是说使用 B+树单次磁盘 I/O 的信息量相比较 B 树更大,I/O 效率更高。
  • MySQL 是关系型数据库,经常会按照区间来访问某个索引列,B+树的叶子节点间按顺序建立了链指针,加强了区间访问性,所以 B+树对索引列上的区间范围查询很友好。而 B 树每个节点的 key 和 data 在一起,无法进行区间查找。

相关文章: