Mysql 哈希索引(hash index)

哈希索引本身在实际项目中使用的并不多,但是常常在面试的时候拿来与B+Tree 索引等进行比较提问,那么哈希索引到底是怎样的结构?又适用于哪些场景呢?有哪些优点和缺点呢?

结构实现

哈希索引(hash index) 是基于哈希表实现,只有精确匹配索引所有列,查询才会有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),哈希码是一个较小的值,并且不同健值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。

特性

因为索引自身只需要存储对应的哈希值,所以索引的结构十分紧凑,这也让哈希索引查询数据的速度非常快,然而,哈希索引也有它的限制(也是面试注意回答的地方):

  • 哈希索引只包含哈希值和行指针,而不存储字段值,所以不能适用索引中的值来避免读取行。不过,访问内存中的行的速度很快,索引大部分情况下这一点对性能的影响并不明显。
  • 哈希索引数据并不是按照索引值顺序存储的,所以也就无法用于排序。
  • 哈希索引也不支持部分索引匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希值的(例如,在数据列(A,B)上建立哈希索引,如果查询只有数据列A,则无法使用该索引)。
  • 哈希索引只支持等值比较查询,包括=,IN(),<=>(注意<>和<=>是不同的操作)。也不支持任何范围查询,例如 where price > 100.
  • 访问哈希索引的数据非常快,除非又很多哈希冲突(不同的索引列值却有相同的哈希值)。当出现哈希冲突的时候,存储引擎必须遍历链表中所有的行指针,逐行进行比较,知道找到所有符合条件的行。
  • 如果哈希冲突很多的化,一些索引维护操作的代价也会很高。例如,如果在某个选择性很低(哈希冲突较多)的列上建立哈希索引,那么当从表中删除一行数据时,存储引擎需要遍历对应哈希值的链表中的每一行,找到并删除对应行的引用,冲突越多,代价越大。

因为这些限制,哈希索引只使用于某些特定的场合。而一旦适合哈希索引,则它带来的性能提升将非常显著。

猜你喜欢

转载自blog.csdn.net/wangxuelei036/article/details/107321198