MySQL查询首次执行耗时8分钟二次执行极快的异常问题咨询
异常现象核心原因分析
1. 首要原因:InnoDB缓冲池冷启动缓存未命中
- 该查询执行计划选择扫描
SU表的u_SU_a索引,按索引顺序查找满足过滤条件的第一条记录。首次执行时,SU表对应的索引页、数据页都未加载到InnoDB缓冲池中,需要全量从磁盘读取。 - 慢查询日志显示两次执行都扫描了200万+行数据,对应约32GB的InnoDB页数据(按默认16KB页大小计算)。首次执行时完全走Azure P30 SSD的随机读,受限于5000 IOPS和200MB/s的带宽,加上随机IO的额外开销,最终耗时472秒。
- 第二次执行时,所有需要的页已经全部缓存到InnoDB缓冲池的内存中,无需访问磁盘,仅需内存扫描200万行数据,因此耗时骤降到3秒左右。
2. 次要辅助原因:操作系统文件系统缓存命中
除了MySQL自身的缓冲池,操作系统层面的文件系统缓存也会缓存最近读取的磁盘数据,进一步降低了第二次执行的IO开销。
验证方法
重启MySQL实例后立即执行该查询,如果耗时再次回到数百秒级别,即可100%确认是缓存未命中导致的耗时差异。
优化建议
新建联合索引 idx_SU_tid_status_a(tid, status, a),该索引可以直接定位到tid=1且status != 'DELETED'的记录,并且索引天然按a排序,不需要扫描全表200万行数据,无论冷热启动都可以毫秒级返回结果。
内容的提问来源于stack exchange,提问作者Kiva
相关产品推荐
相关产品推荐

