MySQL 5.7 中 query_cache_type 已弃用,设为1或2也无效,Qcache_hits恒为0,因Server层缓存入口被绕过;推荐显式设为0,并改用Redis或ProxySQL等外部缓存。

MySQL 5.7 中 query_cache_type 已被弃用,无法真正开启查询缓存。即使你手动设置 query_cache_type = 1 并重启服务,SHOW VARIABLES LIKE 'query_cache_type' 可能仍显示 ON,但实际缓存逻辑已被移除,Qcache_hits 永远为 0。
为什么在 MySQL 5.7 里设了 query_cache_type 却没效果
MySQL 官方从 5.7.20 开始将查询缓存标记为“deprecated”,5.7.33 及之后版本(包括所有 8.0 版本)彻底移除该功能。但部分 5.7.x 早期小版本(如 5.7.19 前)仍保留代码路径,导致配置看似生效——query_cache_size 非零、query_cache_type 显示为 ON,但运行 SHOW STATUS LIKE 'Qcache%' 会发现 Qcache_hits 和 Qcache_inserts 始终是 0,且内存未被实际占用。
- 根本原因:Server 层的缓存入口函数已被绕过,SQL 执行流程跳过了缓存检查阶段
- 典型表现:
SELECT * FROM t WHERE id = 1连续执行多次,Qcache_hits不增长 - 验证方式:执行
SELECT @@query_cache_type, @@query_cache_size;后再查SHOW STATUS LIKE 'Qcache%',若所有Qcache_*值全为 0,说明缓存未工作
query_cache_type 的三个取值在 5.7 中的实际行为
尽管文档仍列出 0 / 1 / 2,但在 5.7 后期版本中它们已失去语义:
-
query_cache_type = 0:不触发任何缓存逻辑(最安全,推荐显式设为 0) -
query_cache_type = 1:变量可设成功,但无实际作用;某些监控脚本可能误判为“已启用” -
query_cache_type = 2(DEMAND):同上,SQL_CACHE提示会被忽略,查询不会进入缓存 - 注意:
have_query_cache在 5.7 中恒为YES,它只反映编译时是否包含旧代码,不能作为功能可用依据
替代方案:别再依赖 query_cache_type,改用更可控的缓存层
原生查询缓存在高并发写场景下本就容易失效,5.7+ 应直接放弃。真实有效的替代路径是:
- 应用层加 Redis 缓存:对确定不变的查询(如字典表、配置项),用
SELECT ... INTO @var+GET封装,命中率可控 - 连接层使用 ProxySQL 或 MaxScale:支持基于 SQL 模板的缓存(如匹配
SELECT * FROM config WHERE type = ?) - 升级到 MySQL 8.0+ 后,彻底删除所有
query_cache_*配置项,避免误导运维和监控系统 - 若必须兼容老代码中的
SQL_NO_CACHE,它会被静默忽略,不影响执行,但也不起作用
真正麻烦的不是配置写错,而是监控指标(如 Qcache_hits / Qcache_inserts)在 5.7 中变成永远为 0 的“幽灵值”——它不会报错,却悄悄让容量规划和性能归因完全失真。


















