mysql 8.0 彻底移除查询缓存模块,相关变量不存在导致启动报错;qps下降主因是persist配置覆盖、统计信息过期和optimizer_switch默认值变更,而非缓存缺失。

MySQL 8.0 不是“关掉了查询缓存”,而是从代码里彻底删了 query_cache_type、query_cache_size 等所有相关变量——配置文件里留着它,mysqld 启动直接失败,报错 Unknown system variable 'query_cache_type'。这不是兼容性问题,是设计层面的放弃。
为什么启动就报错?因为变量真没了
MySQL 8.0.3 起,整个 Query Cache 模块被物理移除。这意味着:
-
SHOW VARIABLES LIKE 'query_cache%'查不到任何结果,不是没启用,是根本不存在 - 配置文件中哪怕只有一行
# query_cache_type = 0(注释状态),某些版本的配置解析器仍会报错退出 -
SELECT SQL_CACHE *语句在语法解析阶段就失败,报错ERROR 1286 (42000): Unknown table engine 'QUERY CACHE' - Percona Server 8.x、MariaDB 10.6+ 同样不识别,别指望“云厂商可能偷偷保留”
性能下降不是因为缓存没了,而是旧配置失效 + 新默认值踩坑
从 5.7 升级到 8.0 后 QPS 下降,90% 的真实原因和“没缓存”无关,而是以下三类问题叠加:
-
PERSIST 机制覆盖了你的
my.cnf:执行过SET PERSIST sort_buffer_size = 64K会写入mysqld-auto.cnf,优先级高于配置文件;查当前生效源:SELECT VARIABLE_NAME, VARIABLE_SOURCE FROM performance_schema.variables_info WHERE VARIABLE_SOURCE = 'PERSISTED' -
统计信息过期导致执行计划失真:
INNODB_TABLESTATS.last_update停在升级前,EXPLAIN显示扫描 10 万行,实际只有 100 行;修复命令:ANALYZE TABLE your_table(对所有慢查涉及的表都执行) -
optimizer_switch默认值变了:比如mrr=off(5.7 是 on)、index_merge=on(8.0 默认开启但常拼错索引);临时验证:SET SESSION optimizer_switch='mrr=on,index_merge=off',再看EXPLAIN FORMAT=TREE
真正该调的两个参数:innodb_buffer_pool_size 和应用层缓存
Query Cache 被淘汰,不是因为“缓存没用”,而是它缓存的是结果集(粗粒度、易失效),而现代优化要的是数据页(细粒度、协同读写)。替代路径很明确:
-
InnoDB 缓冲池必须调:设为物理内存的 50%–75%,例如 16GB 内存服务器可设
innodb_buffer_pool_size = 12G;注意单位写法,12G或12288M有效,12288(无单位)会被当字节处理 -
高频固定结果集交给 Redis:比如用户配置、地区列表、开关状态;Key 设计要语义化,如
config:feature_flags,避免用SELECT * FROM config WHERE type='flag'的哈希值作 Key -
SQL 层能做的,是减少 I/O 而非依赖缓存:用覆盖索引避免回表、延迟关联(
JOIN (SELECT id FROM t WHERE ...))、拆解大IN子查询——这些重写不依赖任何缓存机制,效果立竿见影
最常被忽略的一点:升级后不检查 performance_schema.variables_info 和 INNODB_TABLESTATS,就急着调 innodb_buffer_pool_size,结果缓冲池设得再大,优化器还在瞎选执行路径,I/O 压力照旧。先让统计信息准,再让数据页热,最后让应用少打 DB——顺序错了,调什么都是白忙。











