Hexo

点滴积累 豁达处之

0%

自适应哈希索引

哈希是一种非常快的查找方法,在一般情况时间复杂度为O(1)。而B+树的查找次数,取决于B+树的高度,在生成环境中,B+树的高度一般为3-4层,故需要查询3-4次。

起由

如果你要在B+树里面找到你的数据,那么你也许要经过3-4次的IO才能找到数据页。那么有没有更快的方式让数据查找更加高效呢?哈希(hash)也许是一个不错的方案,一般情况下,在哈希表中查找一条数据的时间复杂度为O(1)
那么hash是完美的么?不,当哈希表中的元素变多时,容易引发哈希冲突,这个时候必须采取一些措施才能保证哈希表的均衡,而在极端的条件下,容易出现一条较长的链表,这对于查找来说反倒是负优化了。
InnoDB也许也想到了这点,它通过一些规则来选择热点数据来参与哈希表的构建,当访问这部分的数据时,可以通过哈希表来更快地找到这些数据。

什么是自适应哈希索引

InnoDB会监控对表上各索引页的查询,如果观察该数据被访问的频次符合规则,那么就建立哈希索引来加快数据访问的速度,这个哈希索引称之为”Adaptive Hash Index,AHI“,AHI是通过缓冲池的B+树页构建的,建立的速度很快,而且不对整颗树都建立哈希索引。(可以理解成热点的数据才会进入这个哈希表)

AHI有一个要求,即对这个页的连续访问模式必须是一样的。例如对于(a,b)这样的联合索引页, 其访问模式可以是以下情况:

1
2
select a from tableA where a = xxx;
select a,b from tableA where a = xxx and b = xxx;

这两个查询都遵循了最左匹配原则,但是他们用到的索引是不一样的,第一个查询用到了a这个索引,第二个查询才完美地覆盖了(a,b)这个联合索引。InnoDB不会对这种交替查询的索引建立自适应哈希索引。也就是说,

  • 必须得保证N次请求,查询的条件都是一致的
  • 同一查询条件进行了100次以上的访问
  • *页通过该模式访问了N次,其中N=页中记录 * 1/16*

优缺点及使用场景

名称 自适应哈希索引
适合使用场景 适合使用 = 和 IN 操作符的等值查询
不合适场景 不适合使用 like 和 % 的范围查询和高并发的joins
优点 提高了Innodb的内存使用率和一些情况下二级索引的查询效率
缺点 占用Innodb的内存缓存,使用了 lacth 锁保护内存中的hash结构

相关参数

可以使用innodb_adaptive_hash_index变量启用AHI;

或者在服务器启用时,禁用skip-innodb-adaptive-hash-index(注释掉)
还有一个参数为innodb_adaptive_hash_index_parts,这个5.7后InnoDB将自适应哈希索引进行了分区处理,每个区对应一个锁,如果大量地访问,那么可能会对性能产生影响(抢锁),InnoDB将这个值设为8,最大可为512。

通过命令SHOW ENGINE INNODB STATUS可以看到AHI的使用情况

参考链接