47 MySQL 内部是否支持查询缓存(Query Cache)?
5.7 及以前支持,8.0 以后不支持
| MySQL | 查询缓存机制 | 状态 |
|---|---|---|
| 5.7 及以前 | 支持query cache | 已不推荐使用 |
| 8.0 及以后 | 不再支持 | 被完全移除 |
- 查询语句完全一致(包括空格)时,直接从缓存返回结果。
- 修改相关表的数据会使对应缓存失效。
-- 启用方式
show variables like 'query_cache_type';
show variables like 'query_cache_size';
-- 启用缓存(老版本配置)
set global query_cache_type = 1;
set global query_cache_size = 1048576; -- 1MB
问题:
- 粒度太粗,更新频繁场景无效;
- 会加重全局锁压力;
- 对 InnoDB表几乎无收益。
MySQL 8.0 起 推荐使用的替代机制
官方推荐:应用层缓存 + InnoDB Buffer Pool +PS/PSA(预处理)
“预处理”是指将 SQL 语句在数据库中预先编译,生成一个执行计划,然后可以多次执行这个编译好的语句,只需要传入不同的参数。这样可以提高性能并提升安全性。
48 mysql8为何废弃掉查询缓存?
-
全局锁竞争严重
- 查询缓存是全局共享资源,任意一个数据更新(如 insert/update)都要更新或失效相关缓存,触发全局锁。
- 高并发场景下,锁竞争激烈,反而拖慢查询效率。
-
缓存命中率低
- 查询缓存要求SQL语句完全一致(包含空格/注释等),一旦不一致就无法命中。
- 绝大多数应用使用ORM或动态拼接SQL,导致命中缓存极低。
-
频繁失效,导致无意义的缓存重建
- 任意表中数据一旦变更,相关缓存全部失效。
- 表更新频率高时,缓存持续被清空 → 重建 → 清空 → 重建,造成严重资源浪费。
-
难以优化和维护
- 无法细粒度的指定缓存粒度,范围、策略。
- 对应InnoDB引擎(事务/行锁设计)来说,查询缓存机制并不适配其架构。
49 MySQL 查询缓存的替代方案
| InnoDB Buffer Pool | 缓存数据页和索引页,自动管理 | 所有读操作,默认启用 |
|---|---|---|
| 应用层缓存(Redis) | 在应用中缓存查询结果,灵活高效 | 读多写少,高并发 |
查询缓存 vs InnoDB Buffer Pool
| 特性 | 查询缓存 | InnoDB Buffer Pool |
|---|---|---|
| 缓存对象 | 完整的 SQL 查询结果 | 数据页和索引页 |
| 缓存粒度 | 查询级别 | 页级别(通常为 16KB) |
| 是否与具体查询相关 | 是,必须完全相同的 SQL 才命中 | 否,与查询语句无关 |