MySQL 8.0 彻底删除查询缓存模块,性能下降主因是PERSIST配置覆盖、统计信息过期和optimizer_switch默认值变更;需清理persisted变量、执行ANALYZE TABLE、校准optimizer_switch及合理设置innodb_buffer_pool_size。

MySQL 8.0 不是“暂时禁用”查询缓存,而是从代码层面彻底删除了 query_cache_type、query_cache_size 等所有相关逻辑——配置即报错,服务无法启动。性能下降的主因不是缓存没了,而是旧配置失效、统计信息过期、优化器默认行为变更这三件事叠加造成的“误判”。调整参数必须围绕这三点展开,而不是找替代缓存开关。
检查并清理 PERSISTED 变量覆盖问题
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被设为 64K),可执行RESET PERSIST;清空(需重启验证)
立刻刷新统计信息,避免优化器“瞎估行数”
5.7 升级到 8.0 后,INNODB_TABLESTATS 表里的 last_update 时间不会自动更新,导致 EXPLAIN 中的 rows 值严重失真(比如显示 10 万行,实际只有 100 行),优化器因此放弃索引走全表扫描。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 查失真程度:
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(8.0 默认开启,但升级后可能被覆盖)
对比并重置 optimizer_switch 默认值
8.0 至少有 12 项 optimizer_switch 子开关默认值变了,比如 mrr=off(5.7 是 on)、index_merge=on(常导致优化器拼凑单列索引,反而绕开你的复合索引)。
- 升级前务必存档 baseline:
SELECT @@optimizer_switch; - 升级后比对差异,重点关注带
=off的项:mrr、use_index_extensions、derived_merge - 临时验证:
SET SESSION optimizer_switch='mrr=on,use_index_extensions=on';,再跑EXPLAIN看执行路径是否恢复 - 若
Extra出现Using intersect()或Using union(),说明index_merge在干扰,可先试SET SESSION optimizer_switch='index_merge=off';
真正容易被忽略的是:这些参数调整必须配合 innodb_buffer_pool_size 重新校准——它不再是“锦上添花”,而是新版本下扛住流量的核心缓冲区。设太小,所有优化都白搭;设太大,又会挤占系统其他进程内存。别只盯着“没了什么”,要盯住“现在靠什么撑住”。

















