应关闭MySQL 5.7的查询缓存,因其在高并发写入下导致缓存命中率低、全局锁争用严重、内存碎片化,且配置残留会自动启用;需从配置文件彻底移除相关参数并重启服务。

要关闭。MySQL 5.7 默认开启 query_cache_type = 1,但它在绝大多数真实业务场景中不是加速器,而是拖慢吞吐的隐性瓶颈。
为什么 query_cache_type = 1 在 5.7 里反而害性能
它不是“偶尔失效”,而是“一写全崩”:任何对表的 INSERT/UPDATE/DELETE/ALTER 都会清空该表所有缓存条目。高并发写入下,缓存命中率常低于 5%,却还要承担每次查询前的 hash 计算、全局 mutex 锁争用、内存碎片管理开销。
- 哪怕只是给日志表加一条记录,所有关联配置表的缓存全丢
- 两个仅差一个空格或注释的 SQL,
SELECT * FROM user和SELECT * FROM user -- get all,完全不共享缓存 -
query_cache_min_res_unit默认 4KB,一个 20KB 结果要分 5 次写入,每次都要抢锁
怎么确认它正在拖慢你
别只看 Qcache_hits 数值高就以为有用——关键看 Qcache_inserts 和 Qcache_lowmem_prunes 的比值。如果后者远高于前者,说明缓存刚写进去就被挤出去了;再配合 Threads_connected 上升但 Queries 吞吐不增,基本就是 query cache mutex 在卡脖子。
- 执行
SHOW STATUS LIKE 'Qcache%';查看实时指标 - 观察
Qcache_free_memory是否长期低于总大小的 10% - 用
perf top -p $(pgrep mysqld)看是否频繁出现query_cache_lock相关符号
关闭它,但别只停在 SET GLOBAL
SET GLOBAL query_cache_type = OFF; 只是运行时关闭,MySQL 重启后又恢复。真正生效必须从配置层根除。
- 在
my.cnf或mysqld.cnf中删掉或注释掉所有相关项:query_cache_type、query_cache_size、query_cache_limit、query_cache_min_res_unit - 重启 MySQL(仅 reload 配置不生效)
- 确认
SHOW VARIABLES LIKE 'query_cache%';全部返回OFF或0
最易被忽略的一点:即使你从没显式开启过 query cache,只要配置文件里留着 query_cache_size = 1048576 这类残留,MySQL 5.7 就会自动把 query_cache_type 拉回 1 —— 它的默认逻辑是“size > 0 → type = 1”。删干净,才真正关掉。


















