前言
我们知道InnoDB
和MyISAM
存储引擎支持的都是B+树索引,还有一个memory
存储引擎(一个基于内存的存储引擎),他支持哈希索引,那么哈希索引到底是怎么回事呢?这就是我们今天要学习的内容。(了解即可)
对于哈希索引(链式哈希表)来说,假设在表中,我们将name设置索引,那么其建立的索引的大致结构如下(简略图):
其中我们根据建立索引的列(name)由哈希函数计算出hashkey后再和桶数取模,将name放进对应的桶中,由此我们也就不难看出,hash表中的元素没有任何顺序可言,所以它也就更适合做等值查询。
- 对于范围搜索,模糊查询、排序等操作等,它都需要遍历整个哈希,不适合。
综上所述,哈希索引存在以下的缺点:
- 没有办法处理磁盘上的数据,从而加载到内存上构建高效的数据结构,因为他没有办法减少磁盘IO的次数。
- 直只适合做等值搜索,其他的范围,排序等不适合。
自适应哈希索引
注意
:此哈希索引并不是我们上面提及的memory支持的哈希索引,而是InnoDB的一个自适应哈希索引。
自适应哈希索引的源头
我们知道,在涉及到回表操作时,既搜索了二级索引树又搜索了主键索引树,InnoDB
存储引擎检测到同样的二级索引不断地被使用,那么它会自动根据这个二级索引,在内存上根据二级索引树(B+树)上的二级索引值,在内存上构建一个哈希索引,来加速搜索。
自适应哈希索引的原理
从上面的图片中,我们也可以看出,自适应哈希索引就是对频繁的回表操作过程中,节省了二级索引树和主键索引树的搜索过程,这就是自适应哈希索引的原理。(也就是对于B+树索引频繁使用回表和二级索引的一种优化方式
)
评判
- 自适应哈希索引本身的数据维护也是要消耗性能的,并不是说自适应哈希索引在任何情况下都会提升二级索引的查询性能!
我们需要根据参数指标,来具体分析是否打开或者关闭自适应哈希索引。show engine innodb sattus\G
能看到两个比较重要的信息:
RW-latch
等待的线程数量,同一个分区等待的线程数量过多时,我们就不应该使用自适应哈希索引了,此时甚至会阻塞线程,不能提高性能。(自适应哈希索引默认分配了8个分区,每一个管理1个或多个桶,每个分区之间可以并行操作,同一个分区内会进行加锁操作进行并行控制)- 自适应哈希索引搜索的频率(低)和二级搜索树搜索的频率(高) ,说明自适应哈希索引并没有帮什么大忙,你可以关闭自适应哈希索引。
总结:索引的常见问题
问题: 当你被问到SQL和索引优化的问题时,怎么切入?
在设置合理的、业务可以接受的慢查询时间后,通过查询慢查询日志,压测执行各种业务,查看慢查询日志,找出所有执行耗时的sql,然后用explain分析这些耗时的sql,之后举一些例子(比如where+order by时,出现了using filesort,涉及了外部排序,这就比较耗时,我就会建立联合索引。。。或者涉及类型强转时,修改sql,或者使用到函数时我们要做一些优化工作。)