MySQL 8.0 起已移除查询缓存,因其以 SQL 文本为 key 导致命中率低、写操作频繁清空、全局锁瓶颈等缺陷;推荐改用 InnoDB 缓冲池、应用层缓存、索引优化等更高效方案。

MySQL 查询缓存(Query Cache)在较老版本(如 5.6、5.7)中存在,但不建议开启,且自 MySQL 8.0 起已被完全移除。它的设计初衷是缓存 SELECT 查询结果,避免重复执行相同语句,但实际使用中副作用远大于收益。
查询缓存的机制与致命缺陷
查询缓存以 SQL 文本为 key,将完整结果集(包括字段名、数据、类型)缓存到内存中。一旦表发生任何写操作(INSERT/UPDATE/DELETE/REPLACE/TRUNCATE/ALTER 等),该表关联的所有缓存条目都会被立即清空。
- 高并发写入场景下,缓存命中率极低,反而因频繁失效带来额外锁开销(query cache mutex)
- 缓存键严格区分大小写、空格、注释、连接方式(如 USE INDEX),两个逻辑等价的 SQL 很可能无法共享缓存
- 缓存空间碎片化严重,管理成本高;全局锁导致在多核 CPU 上成为性能瓶颈
比查询缓存更有效的替代方案
现代 MySQL 性能优化应绕过 query cache,转向更可控、更底层的加速手段:
- InnoDB 缓冲池(innodb_buffer_pool_size):优先保障热数据页常驻内存,对读密集型场景效果显著
- 应用层缓存(如 Redis、Memcached):由业务控制缓存粒度、过期策略和更新时机,灵活性强
- 索引优化 + 执行计划分析(EXPLAIN):减少全表扫描,让查询本身更快,比“缓存慢查询”更有意义
- 从库读分离或只读副本缓存:在从节点启用缓存逻辑(如 ProxySQL 的 query rule),规避主库写影响
如果你仍在用 MySQL 5.7 及以下版本
确认是否已关闭查询缓存(推荐做法):
- 检查状态:
SHOW VARIABLES LIKE 'query_cache_type';—— 值应为OFF - 检查是否禁用:
SHOW VARIABLES LIKE 'query_cache_size';—— 值应为0 - 若曾开启过,重启后生效;运行时可通过
SET GLOBAL query_cache_type = OFF;临时关闭(需 SUPER 权限)
不要依赖 SQL_NO_CACHE 局部绕过——这说明你已经意识到它不可靠,不如全局关掉来得干净。
不复杂但容易忽略:真正影响查询速度的,从来不是“要不要缓存结果”,而是“能不能不查那么多、不查那么慢”。










