MySQL InnoDB Engine--自适应哈希索引总结
功能特性
在MySQL中,对哈希索引的访问仅需要一次HASH计算即可定位到目标位置,而对B树索引的访问需要依次访问根节点>中间节点>叶子节点。
为优化B树索引需要访问多个"非叶子节点页"才能定位到"叶子节点页"的问题,InnoDB存储引擎通过哈希索引来帮助查询快速找到"目标叶子节点页"以提高查询性能。
InnoDB存储引擎通过监控表上索引页的查找模式,自动根据查找模式对"热点数据"来创建哈希索引,因此被成为自适应哈希索引。
自适应哈希索引使用Buffer pool中的数据页进行构造,仅保存在内存中,不会持久化到磁盘上,且仅对热点数据进行处理,因此构造自适应哈希索引速度极快。
自适应哈希索引不会对同一数据页中所有记录进行索引,而是根据访问模式决定对相同键值的记录进行如何索引,如对"大于等于"和"小于等于"两种模式采用不同方式。
InnoDB存储引擎仅支持B树索引,不支持哈希索引和全文索引。
可以通过SHOW ENGINE INNODB STATUS命令来查看当前实例上自适应哈希索引的使用情况,如
------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 0, seg size 2, 0 merges merged operations: insert 0, delete mark 0, delete 0 discarded operations: insert 0, delete mark 0, delete 0 Hash table size 796967, node heap has 0 buffer(s) Hash table size 796967, node heap has 0 buffer(s) Hash table size 796967, node heap has 343 buffer(s) Hash table size 796967, node heap has 0 buffer(s) Hash table size 796967, node heap has 0 buffer(s) Hash table size 796967, node heap has 2 buffer(s) Hash table size 796967, node heap has 1 buffer(s) Hash table size 796967, node heap has 3 buffer(s) 0.00 hash searches/s, 0.00 non-hash searches/s
PS1: SHOW ENGINE INNODB STATUS命令用来展示存储引擎一段时间的状态数据,而非当前数据。
PS2: hash searches和non-hash searches可能不准,在相同访问频率下,其值从几十暴涨至几十万。
支持操作
自适应哈希索引是针对B+树索引的查找模式来优化,其支持的操作类型有:
1、唯一查找(Unique Scan)
2、范围查找(Range Scan locat first key page)
3、增删改(INSERT/DELETE/UPDATE)
使用条件
1、使用索引访问17次(BTR_SEARCH_HASH_ANALYSIS)
2、使用相同查找模式访问100次(BTR_SEARCH_BUILD_LIMIT)
3、数据页被相同模式访问N次(N=页中记录*1/16)
功能优点
根据InnoDB存储引擎官方的文档显示,启用AHI后:
1、读取和写入速度可以提高2倍
2、辅助索引的连接操作性能可以提高5倍
功能缺点
1、对热点数据页构造自适应哈希索引需要相同模式连续执行,使用不同访问模式交替执行不会触发,无法控制业务访问顺序。
2、自适应哈希索引在DML操作引发的数据变化时处理效率成本较高,需要根据不同类型操作对哈希索引进行维护。
3、自适应哈希索引在维护哈希索引时使用全局latch对象来限制并发,可能影响到业务并发性能。
4、自适应哈希索引使用缓存池内存来存放哈希索引数据,可能会内存占用过多导致缓存池数据命中率降低和磁盘读操作增加。
功能缺陷
在使用自适应哈希索引时应关注其锁争用情况,极端情况下会导致数据库异常宕机。
You can monitor the use of the adaptive hash index and the contention for its use in the SEMAPHORES section of the output of the SHOW ENGINE INNODB STATUS command.
If you see many threads waiting on an RW-latch created in btr0sea.c, then it might be useful to disable adaptive hash indexing.
Sometimes, the read/write lock that guards access to the adaptive hash index can become a source of contention under heavy workloads, such as multiple concurrent joins.