Adaptive Hash Index(自适应hash索引)

1.1 什么是hash索引

  哈希索引基于哈希表实现,只有精确匹配索引所有列的查询才有效,对于每一行数据,存储引擎都会对所有的索引列的值计算一个哈希码,哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。

  • 哈希索引只包含哈希值和行指针,而不存储字段值,所以不能使用哈希索引来做覆盖索引扫描。
  • 哈希索引数据并不是按照索引列的值顺序存储的,所以也就无法用于排序。
  • 哈希索引也不支持部分索引列匹配查找,因为哈希索引始终是使用索引的全部列值内容来计算哈希值的。哈希索引只支持等值比较查询。
  • 访问哈希索引的数据非常快,除非有很多哈希冲突,当出现哈希冲突的时候,存储引擎必须遍历链表中所有的行指针,逐行进行比较,直到找到所有符合条件的行。如果哈希冲突很多的话,一些索引维护操作的代价也很高。

1.2 什么是自适应hash索引

  在MySQL中,哈希索引只有Memory, NDB两种引擎支持,Memory引擎默认支持哈希索引,如果多个hash值相同,出现哈希碰撞,那么索引以链表方式存储。对于我们常用的InnoDB引擎,是不支持哈希索引的;要使InnoDB支持哈希索引,可以通过伪哈希索引来实现,叫自适应哈希索引。

  自适应哈希索引就是当InnoDB注意到某些索引值被使用的非常频繁时,它会在内存中基于btree索引之上再创建一个哈希索引,这样就可以进行哈希查找。

1.3 自适应hash索引原理

  InnoDB存储引擎会监控对表上索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立自适应哈希索引,实现本质上就是一个哈希表:从某个检索条件到某个数据页的哈希表。

索引使用大于17次
  AHI是为某个索引树建立的(当该索引树层数过多时,AHI才能发挥效用)。如果某索引只被使用一两次,就为之建立AHI,会导致AHI太多,维护成本高于收益。当某一索引使用次数大于17次时,即通过筛选。

hash info使用次数大于100
  对使用次数大于17次的索引建立hash info,hash info是用来描述一次检索的条件与索引匹配程度。建立AHI时,就可以根据匹配程度,抽取数据中匹配的部分,作为AHI的键。当hash info使用次数大于100代表该hash info为经常使用的hash info。

  • hash info结构:匹配索引列数,下一列匹配字节数,是否从左匹配。

hash info命中页数据大于1/16
  果我们为表中所有数据建立AHI,那AHI就失去了缓存的意义,所以要找出该索引树上经常使用的数据页,通过该步骤筛选后就可以开始建立hash 索引。

1.4 相关变量

mysql>  show variables like '%hash%';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| innodb_adaptive_hash_index       | ON    |
| innodb_adaptive_hash_index_parts | 8     |
+----------------------------------+-------+
2 rows in set (0.00 sec)
#innodb_adaptive_hash_index:控制innodb自适应哈希索引特性是否开启参数
innodb_adaptive_hash_index_parts:凡是缓存都会涉及多个缓存消费者间的锁竞争。MySQL通过设立多个AHI分区,每个分区使用独立的锁,来减少锁竞争。

1.5 监控指标

-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
 #这行显示自适应哈希索引的状态,其中,Hash table size 276707表示AHI的大小, node heap has 629 buffer(s)表示AHI的使用情况
Hash table size 276707, node heap has 2 buffer(s)
Hash table size 276707, node heap has 629 buffer(s)
Hash table size 276707, node heap has 1 buffer(s)
Hash table size 276707, node heap has 0 buffer(s)
Hash table size 276707, node heap has 1 buffer(s)
Hash table size 276707, node heap has 0 buffer(s)
Hash table size 276707, node heap has 2 buffer(s)
Hash table size 276707, node heap has 4 buffer(s)
#这行显示了在show engine头部的时间内Innodb每秒完成了多少哈希索引操作,3999.00 hash  searches/s表示每秒使用AHI搜索的情况,2326.97 non‐hash searches/s表示 每秒没有使用AHI搜索的情况(因为哈希索引只能用于等值查询,而范围查询,模糊查询是不能使用哈希索引的。),通过hash searches: non‐hash searches 的比例大概可以了解使用哈希索引后的效率,自适应哈希索引无法配置,但是可以通过 innodb_adaptive_hash_index=ON|OFF参数来选择是否需要这个特性
3999.00 hash searches/s, 2326.97 non-hash searches/s

  如果你的业务AHI使用率过低,理解了AHI建立的原理后,就可以分析该业务为何不命中AHI,来判断业务是否合理,是否需要改变访问模式或者将数据冷热隔离。也可以考虑关闭AHI,减少AHI的维护成本。

1.6 总结

  • MySQL引入AHI作为查询数据页的缓存,想降低查询数据页的成本

  • AHI的"自适应"想解决的问题是 缓存不能太大,也不能太小

  • AHI建立的过程中,通过不断限制条件,只为经常使用的索引和经常使用的数据页建立缓存

猜你喜欢

转载自blog.csdn.net/qq_42979842/article/details/108041608