MySQL 5.7升级到8.0后查询变慢主因是优化器更依赖真实数据但统计信息过期、optimizer_switch默认值变更及innodb_buffer_pool_size未适配,需立即执行ANALYZE TABLE、调整optimizer_switch并增大缓冲池。

MySQL 5.7 升级到 8.0 后查询变慢,不是缓存没了导致的,而是优化器“突然认真了”,但你没给它准数据、也没配对参数——ANALYZE TABLE、optimizer_switch、innodb_buffer_pool_size 这三样不调,光加索引也救不回来。
为什么 EXPLAIN 显示 type=ALL,明明有索引?
这是最常见信号:优化器误判索引选择性。5.7 升 8.0 后,INNODB_TABLESTATS 表里的 last_update 时间仍卡在升级前,导致估算行数严重失真(比如实际 200 行,它以为是 15 万行,直接放弃索引)。
- 查失真程度:
SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESTATS WHERE TABLE_NAME = 'your_table',看last_update是否早于升级时间 - 交叉验证:
SHOW INDEX FROM your_table查Cardinality,再对比SELECT COUNT(DISTINCT your_col) FROM your_table;差 10 倍以上基本确认统计失效 -
innodb_stats_auto_recalc=ON不是万能的——它只对单次变更超 10% 行数的表触发,冷表永远不动 - 立刻执行:
ANALYZE TABLE your_table(所有慢查涉及的表都要跑) - 长期建议:
SET GLOBAL innodb_stats_persistent = ON,避免后续频繁失效
ORDER BY 突然走 Using filesort,且越查字段越多越慢
MySQL 8.0.20+ 彻底废弃 max_length_for_sort_data,不再按字段长度切分排序模式。原来靠索引有序扫描的查询,现在一律走 filesort;一旦 sort_buffer_size 不够或字段太长,立刻写磁盘临时文件。
智能模型自动切换 V5.0.2 - 多模态感知,自动识别图片/视频/音频/代码/文本任务,切换最优模型。支持图片理解(qwen3-vl-plus)、视频音频(qwen3.5-plus)、代码(glm-5)、Office文档(MiniMax-M2.5)、推理等场景。零感知切换,无需手动操作。
- 判断是否真走索引排序:
EXPLAIN输出中Extra列不含Using filesort才算成功 - 临时验证:在 SQL 开头加
/*+ USE_INDEX(@sel_1 tbl_name (idx_a_b_c)) */强制走复合索引 - 长期方案:补全复合索引,例如
WHERE a=1 ORDER BY b,c就建INDEX(a,b,c) - 别用
SELECT *加剧恶化——字段越多,filesort内存压力越大;可先试SELECT a,b,c看是否恢复
FORCE INDEX 失效,EXPLAIN 冒出 Using index_merge
MySQL 8.0.19+ 默认开启 index_merge=on,优化器会主动把多个单列索引“合并使用”,哪怕你写了 FORCE INDEX (idx_composite),它也可能无视并改走 idx_a,idx_b 合并路径。
- 查当前开关:
SELECT @@optimizer_switch,确认其中index_merge=on是否启用 - 临时禁用:
SET SESSION optimizer_switch='index_merge=off' - 注意:
index_merge在多条件OR查询中常有收益,盲目关掉可能影响其他语句 - 更稳方案:删掉冗余单列索引,保留覆盖性更强的复合索引(例如删掉
INDEX(a)和INDEX(b),只留INDEX(a,b))
为什么 innodb_buffer_pool_size 现在必须设得更大?
因为 InnoDB 成为绝对默认引擎,且 Buffer Pool 现在还缓存数据字典、DDL 日志等元数据。旧配置下容易出现“明明内存充足,却频繁刷脏页”的现象,甚至触发隐式降级行为。
- 建议值收紧为:物理内存的 ≥75%,且必须 ≥2GB——低于 2GB 会触发不稳定降级
- 若启用了
innodb_buffer_pool_chunk_size,需确保innodb_buffer_pool_size是它的整数倍,否则启动时会被静默向下取整 - 检查是否生效:
SELECT @@innodb_buffer_pool_size / 1024 / 1024 AS mb;确认实际分配值 - 预热不一定起作用:若上次
innodb_buffer_pool_dump_at_shutdown没成功(如崩溃退出),预热文件为空,innodb_buffer_pool_load_at_startup=ON无效
真正卡住性能的,往往不是某条 SQL 或某个索引,而是统计信息过期 + optimizer_switch 默认值突变 + 缓冲池配置未适配这三者叠加。尤其要注意 PERSIST 机制:如果升级前有人执行过 SET PERSIST sort_buffer_size = 64K,你改了 my.cnf 也白搭——得先 RESET PERSIST 再重启验证。

















