mysql 8.0性能下降主因是旧配置被persist覆盖、统计信息过期及optimizer_switch默认值变更;需查persisted_variables、运行analyze table、比对并调优optimizer_switch,三者同步交叉验证。

不是MySQL 8.0变慢了,而是你升级后没检查实际生效的配置、统计信息和优化器开关——旧配置被PERSIST覆盖、INNODB_TABLESTATS时间戳卡在5.7、optimizer_switch默认值已悄悄改掉,三者叠加直接让优化器“认不出”你的表。
查persisted_variables是否锁死了关键参数
MySQL 8.0 的 SET PERSIST 会把变量写进 mysqld-auto.cnf,该文件优先级高于 my.cnf。你改了配置文件却没生效?八成是它在起作用。
- 查当前持久化变量:
SELECT * FROM performance_schema.persisted_variables; - 看变量来源和路径:
SELECT VARIABLE_NAME, VARIABLE_SOURCE, VARIABLE_PATH FROM performance_schema.variables_info WHERE VARIABLE_SOURCE IN ('PERSISTED', 'CONFIG'); - 重点盯住:
sort_buffer_size、innodb_buffer_pool_size、optimizer_switch—— 这三个最常被误锁 - 测试环境可临时清空:
RESET PERSIST;,再重启验证是否恢复预期配置
确认optimizer_switch有没有绕开你的索引
MySQL 8.0 至少有 12 项 optimizer_switch 子开关默认值变了,比如 mrr=off(5.7 是 on)、index_merge=on(开启后可能拼凑单列索引,反而跳过你建好的复合索引)。
- 升级前务必存档 baseline:
SELECT @@optimizer_switch; - 升级后比对差异,重点关注带
=off的项:mrr、use_index_extensions、derived_merge - 若
EXPLAIN的Extra出现Using intersect()或Using union(),说明index_merge在干扰,可临时关掉:SET SESSION optimizer_switch='index_merge=off'; - 验证执行路径:
SET SESSION optimizer_switch='mrr=on,use_index_extensions=on';,再跑EXPLAIN
运行ANALYZE TABLE刷新过期的统计信息
5.7 升 8.0 后,INNODB_TABLESTATS 表里的 last_update 时间仍停留在升级前,优化器就以为某张表有 10 万行,实际才 100 行——于是放弃索引,走 type: ALL。
- 查失真程度:
SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESTATS WHERE TABLE_NAME = 'your_table';,对比SHOW INDEX FROM your_table中的Cardinality和SELECT COUNT(DISTINCT your_col) FROM your_table - 立刻修复:
ANALYZE TABLE your_table;(对所有慢查询涉及的表都执行) - 长期建议设
innodb_stats_persistent = ON,避免后续频繁失效
别忽略max_length_for_sort_data已被废弃的事实
MySQL 8.0.20+ 彻底废弃了 max_length_for_sort_data 参数,排序逻辑改为全字段排序优先。如果你的 SQL 有 ORDER BY + LIMIT 且没索引,SELECT * 会比只选几列慢数倍——这不是 bug,是行为变更。
- 现象:同一条
ORDER BY查询,5.7 耗时稳定在 1 秒,8.0 随SELECT字段增多线性变慢,SELECT *达到 4 秒 - 验证方式:用
EXPLAIN FORMAT=TREE看是否出现Using filesort及其代价估算 - 解法优先级:加覆盖索引 > 改写为只查必要字段 > 检查是否真需要
ORDER BY全表
真正容易被忽略的是:这些机制不是孤立起作用的。比如 index_merge=on 让优化器选错索引,叠加统计信息过期,再碰上排序字段无索引,三条路一起堵死,EXPLAIN 看起来像随机抛硬币。排查时别只盯一条线,得同步交叉验证 variables_info、INNODB_TABLESTATS 和 EXPLAIN FORMAT=TREE 输出。











