mysql 8.0+ 已彻底移除查询缓存,query_cache_type等参数无效且启动时警告;官方自8.0.3起删除该模块,不再参与sql执行;高写入场景下其全局锁和低命中率反而拖慢性能,应改用应用层缓存与索引优化。

如果你在 MySQL 8.0 或更高版本中还在配置 query_cache_size、query_cache_type,这些参数已被完全删除,设置无效且启动时会报警告。官方从 8.0.3 版本起正式移除查询缓存模块——它不再参与任何 SQL 执行路径。
这意味着:你根本不需要“避免无效的查询缓存”,因为缓存压根不存在。常见误解是看到慢查询后怀疑“缓存没命中”或“缓存失效了”,其实只是执行计划本身低效,或缺少索引。
查询缓存(Query Cache)不是按 TTL 失效,而是基于表级变更强一致性失效:只要某张表被写入(哪怕只改一行),所有涉及该表的缓存结果立即清空。这不是“懒刷新”,是同步阻塞式失效。
-
INSERT、UPDATE、DELETE、REPLACE、LOAD DATA INFILE都会触发失效 -
ALTER TABLE、DROP TABLE、TRUNCATE TABLE同样清空全部关联缓存 - 即使查询带了
SQL_NO_CACHE,写操作仍会让其他带SQL_CACHE的旧结果失效 - 使用临时表(
CREATE TEMPORARY TABLE)或用户变量(@var := …)的语句,本身就不会进入缓存
查询缓存的锁粒度很粗:每次写入都会对整个查询缓存加全局排他锁(LOCK_query_cache),所有后续读请求必须排队等待锁释放。在 OLTP 系统中,这极易成为瓶颈。
- 缓存命中率低于 10% 时,维护开销(内存管理、哈希查找、锁竞争)远超收益
-
query_cache_min_res_unit设置过小 → 内存碎片严重;过大 → 浪费空间且降低命中率 - 缓存键是完整 SQL 文本(含空格、大小写、注释),
SELECT * FROM t和SELECT * FROM t被视为两条不同查询 - 不支持任何参数化,
WHERE id = 1和WHERE id = 2完全无法共享缓存
与其纠结查询缓存是否有效,不如把精力放在真正可控的地方:
- 用
EXPLAIN检查慢查询是否走了索引,尤其注意type是否为ALL、key是否为NULL - 对高频读、低频写的业务数据(如配置表、城市列表),在应用侧用 Redis 缓存结果,并在写库时主动
DEL对应 key - 避免在 WHERE 中对字段做函数操作(如
WHERE YEAR(create_time) = 2024),导致索引失效 - 监控
Threads_created和Created_tmp_disk_tables,它们比查询缓存命中率更能反映真实性能瓶颈
最常被忽略的一点:很多人升级到 8.0 后仍保留旧版配置文件里的 querycache* 参数,MySQL 虽不报错但会静默忽略——你以为关了缓存,其实连关的动作都不需要。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/251650.html