MySQL 8.0 已彻底移除查询缓存,5.7 及以前版本中缓存命中发生在 SQL 解析前的字面量级比对,依赖 query_cache_type 启用且受多种条件限制;官方自 5.7.20 起弃用,8.0.0 正式删除,应改用应用层缓存或优化索引与缓冲池。

MySQL 查询缓存(Query Cache)在 8.0 版本中已被彻底移除,所以如果你用的是 MySQL 8.0+,query_cache_type、QUERY CACHE 相关机制根本不存在——查询缓存命中这件事,压根不会发生。
MySQL 5.7 及更早版本:缓存命中发生在解析前
在启用查询缓存的前提下(query_cache_type = ON),MySQL 在收到客户端请求后,会先对完整 SQL 字符串做“字面量级”比对:
- SQL 必须完全一致(包括空格、大小写、注释),哪怕多一个空格都不命中
- 不解析语法,不展开视图,不替换变量,不走任何优化器逻辑
- 只要字符串匹配 + 对应表未被修改(通过表变更计数器判断),就直接返回缓存结果
这意味着缓存命中发生在 SQL 解析(parsing)之前,是整个执行路径里最早可能拦截请求的环节。
为什么你查不到“缓存命中率”相关指标?
因为从 MySQL 5.7.20 开始,官方已将查询缓存标记为 deprecated;8.0.0 正式删除。如果你在 5.7 上启用了它,但发现 SHOW STATUS LIKE 'Qcache%' 返回全零或无响应,常见原因有:
-
query_cache_size = 0(即使query_cache_type = 1,没内存也白搭) - SQL 中含不确定函数(如
NOW()、USER()、SELECT ... FOR UPDATE)会被自动排除缓存 - 涉及临时表、系统表(
information_schema)、或者使用了用户自定义函数(UDF) - 表上有活跃的写操作,导致缓存频繁失效(这也是它被废弃的主因之一)
替代方案:别依赖 Query Cache,改用更可控的缓存层
现代应用中,真正有效的缓存应该由业务控制,而不是交由 MySQL 自动管理。例如:
- 应用层用 Redis 缓存热点查询结果,键名可包含参数哈希(如
user:profile:sha256("id=123")) - 用
SELECT SQL_NO_CACHE ...显式绕过旧版缓存(仅限 5.7 及以前) - 升级到 MySQL 8.0 后,把精力放在索引优化、执行计划分析(
EXPLAIN FORMAT=TREE)、以及利用innodb_buffer_pool_size提升数据页缓存效率上
SELECT /*+ USE_INDEX(t, idx_status) */ id, name FROM orders t WHERE status = 'pending' LIMIT 100;
真正容易被忽略的是:很多团队还在文档或监控脚本里保留 Qcache_hits 指标采集逻辑,而生产库早已是 8.0 —— 这类指标不仅无效,还会掩盖真实瓶颈。










