MySQL 8.0 彻底移除了查询缓存(query_cache),包括所有相关变量和逻辑,执行 SHOW VARIABLES LIKE 'query_cache%' 返回空,设置 query_cache_type 会报错;其被删除主因是高并发下全局锁争用严重、内存开销大且命中率低,现由 InnoDB 缓冲池等更优机制替代。

MySQL 查询缓存(query_cache)已彻底移除
MySQL 8.0 起,query_cache_type、query_cache_size 等所有查询缓存相关变量和逻辑已被完全删除。如果你在 8.0+ 版本中执行 SHOW VARIABLES LIKE 'query_cache%',结果为空;设置 query_cache_type=1 会报错 Unknown system variable 'query_cache_type'。这不是配置失效,而是代码级移除——它不再参与任何 SQL 执行流程。
5.7 及更早版本中,查询缓存如何干扰 SQL 执行
在启用查询缓存的旧版本中,一条 SELECT 语句的执行流程实际是:先查缓存 → 命中则跳过解析/优化/执行 → 直接返回结果。这带来几个关键副作用:
- 缓存键基于完整的 SQL 文本(含空格、大小写、注释),
SELECT * FROM t和select * from t视为两条不同语句 - 只要表
t发生任何INSERT/UPDATE/DELETE,该表关联的所有缓存条目立即失效 - 缓存命中时,
SQL_NO_CACHE不生效;而加了SQL_CACHE的语句,即使结果集超大也会尝试缓存,可能拖慢整体性能 -
SELECT NOW()、SELECT RAND()这类非确定性函数,每次执行结果不同,但旧缓存机制仍会缓存第一次的结果,导致数据错误
为什么现代 MySQL 彻底放弃查询缓存
根本原因是它在高并发写入场景下成为严重瓶颈:
- 缓存锁粒度粗:任意表更新都会触发全局缓存锁,阻塞其他查询缓存操作
- 内存碎片与管理开销大:缓存块分配/回收依赖全局 mutex,在多核机器上反而降低吞吐
- 收益极低:真实业务中,相同 SQL 文本重复执行比例远低于预期;而代价(锁争用、内存占用、失效风暴)却随写入量线性上升
- 替代方案更优:InnoDB 缓冲池(
innodb_buffer_pool_size)对热数据页的缓存效率更高,且无语句级一致性负担
迁移或排查时必须检查的残留痕迹
升级到 8.0 后,若应用仍带 SQL_CACHE 或 SQL_NO_CACHE 提示,MySQL 会直接忽略它们——不报错,也不生效。但以下情况需手动处理:
-
配置文件(如
my.cnf)中残留的query_cache_type=1等行,启动时会被静默跳过,建议彻底删除以免误导 - 监控脚本若还依赖
Qcache_hits、Qcache_inserts等状态变量,会查不到值,需改用Com_select+Innodb_buffer_pool_read_requests等指标估算有效命中 - ORM 或中间件生成的 SQL 若硬编码了
SQL_CACHE,虽不影响运行,但属于冗余噪声,建议清理
SELECT /*+ NO_CACHE */ id FROM users WHERE status = 1;
上面这个注释在 MySQL 中无效——NO_CACHE 不是 MySQL 支持的 optimizer hint;真正能绕过缓冲池读取的是 SELECT ... FOR UPDATE 或强制磁盘读的调试手段,但日常无需干预。重点始终是调优 innodb_buffer_pool_size 和索引设计,而不是怀念一个被删掉的功能。










