MySQL自适应Hash索引

Hash索引

Hash是一种查找数据非常快的数据结构,在正常情况下这种查找的时间复杂度为O(1),即一般仅需要一次查找就能定位数据,正常情况是指不存在哈希冲突的情况;而B+树的查找次数,取决于B+树的高度,B+树的高度一般为34层,所以一般最少需要34次的查询。

InnoDB的Hash索引

InnoDB存储引擎会监控对表上各索引页的查询,如果监控到某个索引页被频繁查询,并诊断后发现如果为这一页的数据创建Hash索引会带来更大的性能提升,则会自动为这一页的数据创建Hash索引,并称之为自适应Hash索引。自适应Hash是通过缓冲池中B+树的页进行构建的,建立速度很快,不需要对整张表的数据都构建Hash索引,所以我们又可以把自适应Hash索引看成是索引的索引,。注意一点就是InnoDB只会对热点页构建自适应索引,且是由InnoDB自动创建和删除的,所以不能人为干预是否在一张InnoDB的表中创建Hash索引。

自适应Hash索引

官方有告诉我们每一种存储引擎所支持的索引结构,在https://dev.mysql.com/doc/refman/5.7/en/create-index.html中可以查看,我们截图保留下:

image-20200409150053986

我们可以看到MyIsam和InnoDB仅支持BTree结构的索引,但是我们在创建的时候却有Hash结构可选择,这是因为啥?细心的话可以发现不论我们在创建索引的时候选择了Hash还是BTree,在保存的时候都会自动转换成BTree,就是这个原因。

但是我们又在官方的https://dev.mysql.com/doc/refman/5.7/en/innodb-adaptive-hash.html页面看到这么一句话:

image-20200409150834710

大致意思是:自适应Hash索引特征能使InnoDB在具有适当的工作负载和足够缓冲池内存的系统上执行的更像内存中的数据库的操作,且不会牺牲事务特性或可靠性,MySQL能基于监视到的搜索规则,使用索引键的前缀构建Hash索引,前缀可以是任意长度,并且可能只有b+树中的某些值出现在Hash索引中,Hash索引其实就是对经常访问的索引页进行构建的。

这又说明其实InnoDB是支持Hash索引的,但并不是真正意义上的Hash,而是通过自己的监视情况自动对某些热点索引值构建的内存Hash。

开启和关闭

默认情况下自适应索引是开启状态,毕竟是可以提升性能的嘛,我们也可以通过命令开启和关闭,并可以查看自适应索引的

  • 开启

    默认就是开启的,可以通过命令show variables like 'innodb_adaptive_hash_index';查看自适应哈希索引的状态,并可以在命令行通过show engine innodb status\G查看自适应Hash索引的使用信息(AHI的大小,使用情况,每秒使用AHI搜索的情况等等)

    image-20200409154256344
  • 关闭

    负载较重的情况下,就不太适合开启自适应Hash索引了,因为这样可以避免额外的索引维护带来的开销,可以在启动的时候通过参数--skip-innodb-adaptive-hash-index关闭