mysql 8.0 中 query_cache_type 已被源码级彻底移除,配置即报“unknown variable”错误并导致启动失败;必须手动删除 my.cnf 中所有以 query_cache_ 开头的行(含注释),且执行流程取消缓存跳过环节,优化器压力增大,innodb 缓冲池成为唯一有效缓存层。

MySQL 8.0 中 query_cache_type 配置直接报错
如果你在 MySQL 8.0+ 的配置文件里还留着 query_cache_type 或 query_cache_size,mysqld 启动时会拒绝启动,并抛出类似 Unknown variable 'query_cache_type=1' 的错误。这不是警告,是硬性移除——源码里相关逻辑已完全删除。
常见误操作包括:从 5.7 升级后未清理旧配置、用 Docker 镜像沿用老版 my.cnf、云数据库控制台模板残留参数。遇到报错,删掉这两行再重启即可,别试图设为 0 或 OFF 来“兼容”。
执行流程从六步变为严格五步,无缓存跳过环节
MySQL 8.0 的 SELECT 执行流程固定为:连接器 → 解析器 → 预处理器 → 优化器 → 执行器 → 结果返回。原先“查询缓存”作为第二步的位置彻底空缺,不再有“命中即返回”路径。
这意味着:
- 所有查询都必须走完解析、预处理、优化、执行全流程,哪怕
SELECT 1这种语句也一样 - 不会因 SQL 文本完全一致而跳过优化器——
SELECT * FROM t WHERE id = 1和SELECT * FROM t WHERE id = 1(末尾多空格)在 5.7 可能分别缓存,但在 8.0 中只是两条独立语句,各自生成执行计划 - EXPLAIN 的输出不再受缓存开关影响,每次调用都真实反映当前优化器决策
优化器压力变大,统计信息不准的影响更明显
没了查询缓存兜底,优化器选错执行计划的后果直接暴露给业务。以前靠缓存“掩盖”了部分慢查询(比如某条 SQL 偶尔走错索引但结果被缓存住了),现在每次执行都实打实走磁盘或 Buffer Pool。
关键影响点:
-
ANALYZE TABLE必须定期执行,尤其在大批量 INSERT/UPDATE 后,否则cardinality失真会导致优化器放弃可用索引 - 隐式类型转换(如
WHERE phone = 13800138000对字符串字段)会直接让索引失效,且无法被缓存“缓冲”,必须修正 SQL 或字段类型 -
EXPLAIN FORMAT=TREE和EXPLAIN FORMAT=JSON中的cost_info字段变得更有参考价值,应纳入日常慢查分析流程
InnoDB Buffer Pool 成为唯一“缓存层”,配置不当性能断崖下跌
查询缓存消失后,真正起作用的缓存只剩 innodb_buffer_pool_size。它不缓存结果,而是缓存数据页和索引页——SQL 走不走索引、快不快,全看这层是否命中。
容易被忽略的实操细节:
- 该值不能只看“内存够不够”,还要配合
innodb_buffer_pool_instances拆分实例数(建议设为 CPU 核心数,至少 8),否则高并发下内部 mutex 争用严重 -
SHOW ENGINE INNODB STATUS里的Buffer pool hit rate应长期保持在 99%+;低于 95% 就得查是不是有大范围全表扫描或 Buffer Pool 不足 - 冷启动后首次查询慢?不是 bug,是 Buffer Pool 空,需预热:可执行
SELECT COUNT(*) FROM t类语句触发页加载,或用innodb_buffer_pool_load_at_startup=ON
最常被低估的一点:没有查询缓存不等于“没法缓”,只是缓存位置变了——从 Server 层下沉到存储引擎层,且与索引强绑定。写 SQL 时少一个 ORDER BY 导致 Using filesort,或者 JOIN 顺序没用对索引,这些问题在 8.0 下再也藏不住了。











