mysql 8.0起查询缓存已彻底移除,不参与任何sql执行流程;所有相关变量(如query_cache_type)被源码级删除,配置即报错,启动失败,缓存行为若存在必为应用层或代理层实现。

MySQL 8.0 之后查询缓存已彻底移除
直接说结论:它不再影响任何 SQL 执行流程。MySQL 8.0(2018年发布)起,query_cache_type、query_cache_size 等所有查询缓存相关变量和逻辑已被完全删除,服务器启动时会忽略这些配置,执行 SHOW VARIABLES LIKE 'query_cache%' 将查不到任何结果。如果你在 8.0+ 环境中看到缓存行为,那一定是应用层(如 Redis、MyBatis 二级缓存)或代理层(如 ProxySQL)做的,不是 MySQL 自身机制。
为什么 5.7 及以前版本的查询缓存会“跳过”执行流程
它不是“影响”流程,而是直接截断流程:命中缓存时,SELECT 语句根本不会进入解析器、优化器、执行器阶段。整个路径变成:客户端请求 → 连接器校验权限 → 查询缓存哈希匹配 → 命中则直接返回结果。
- 缓存键是原始 SQL 文本的 MD5(含空格、大小写、注释),
SELECT * FROM t和select * from t是两条不同缓存 - 只要表被
INSERT/UPDATE/DELETE/ALTER TABLE修改,该表所有缓存条目立即失效 - 含
NOW()、RAND()、用户变量、临时表、系统表(mysql、information_schema)的查询一律不缓存 - 即使配置了
query_cache_type=ON,如果权限校验失败(如无SELECT权限),也不会查缓存,直接报错
误配 query_cache_type=DEMAND 会导致什么
这是 5.7 最容易踩的坑:设成 DEMAND 后,普通 SELECT 不进缓存,但开发者可能忘记加 SQL_CACHE 提示,结果看似“没缓存”,实则是自己关掉了——而错误日志里不会报任何警告。
-
SELECT * FROM users WHERE id = 1→ 不缓存 -
SELECT SQL_CACHE * FROM users WHERE id = 1→ 才进缓存 - 若应用代码生成 SQL 时未注入
SQL_CACHE,即使缓存空间充足也毫无作用 -
SQL_NO_CACHE会强制跳过缓存,哪怕语句本身符合缓存条件
Buffer Pool 和查询缓存完全是两回事
别混淆:InnoDB 的 Buffer Pool 缓的是数据页(page),是存储引擎层的物理读写优化;查询缓存缓的是完整结果集(result set),是 Server 层的逻辑结果复用。前者在所有 MySQL 版本中都关键,后者只存在于 5.7 及更早版本且默认关闭。
真正需要关注的缓存行为,现在只看 innodb_buffer_pool_size、innodb_buffer_pool_instances,以及是否启用了 innodb_change_buffering —— 这些才决定 SELECT 和 UPDATE 的实际性能路径。











