自适应Hash索引(Adatptive Hash Index,内部简称AHI)是InnoDB的三大特性之一,还有两个是 Buffer Pool简称BP、双写缓冲区(Doublewrite Buffer)。自适应Hash索引 = 自适应 + hash索引: 1、自适应即我们不需要自己处理,当InnoDB引擎根据查询统计发现某一查询满足hash索引的数据结构特点,就会给其建立一个hash索引;2、hash索引底层的数据结构是散列表(Hash表),其数据特点就是比较适合在内存中使用,自适应Hash索引存在于InnoDB架构中的缓存中(不存在于磁盘架构中),见下面的InnoDB架构图。还有Hash表的数据结构不支持区间查询,不能进行排序,like查询等,比较适合等值查询。
即这里的自适应Hash索引相当于B+Tree索引的基础上建立的索引,Mysql中只有Memory引擎支持hash索引,而Oracle也是支持Hash索引的,所以InnoDB层自己加了一个Hash索引。只要符合Hash数据结构的特点,比如不用范围查询,而是(where XX = ?)的查询特别多,InnoDB引擎就会自动建立Hash索引。 我们知道B+树索引是一棵多路平衡查找树,当1200路左右时,可以存储接近17亿的数据,而树的层级为4层左右,并且平常搜索树的查询时间复杂度是O(logN)。当查询到节点处时,也可以理解内部大致为二分查询时间复杂度也是O(logN),即B+树索引的读写时间复杂度是O(logN). 而Hash索引读写的时间复杂度近似O(1). InnoDB存储引擎官方的文档显示,启用AHI后,读取和写入速度可以提高2倍,辅助索引的连接操作性能可以提高5倍。
innodb_adaptive_hash_index = off进行关闭。自适应Hash索引使用分片进行实现的,分片数可以使用配置参数设置:innodb_adaptive_hash_index_parts = 8,默认是8个分片最大支持配置 512。并且在 Mysql 5.7之前的分片会使用同一把锁,可能存在并发问题,即Hash索引反而照成了性能问题。信息会被写入”btr0sea.c“文件中,即如果出现有线程在等待”RW-latch“,。 但是后面的版本会使用多把锁解决并发问题。
我们可以通过 show engine innodb status 查看引擎的使用情况,就可以看到自适应hash索引的分片情况,已经使用hash索引和不走hash索引的情况比例(hash search ,non - hash search),如下图: