查询缓存为何 8.0 移除
查询缓存是什么
查询缓存(Query Cache)是 MySQL 在 Server 层的一个优化特性:将 SELECT 语句的完整结果缓存起来,相同的查询直接返回缓存结果,跳过解析、优化和执行。
graph TD
A[SELECT * FROM user WHERE id=1] --> B{查询缓存中<br/>是否存在?}
B -->|命中 ✅| C[直接返回缓存结果]
B -->|未命中 ❌| D[正常执行流程]
D --> E[将结果写入缓存]
E --> F[返回结果]
看似美好,实则鸡肋
问题一:缓存失效太频繁
-- 第一次查询,缓存建好了
SELECT * FROM product WHERE id = 1; -- 缓存命中
-- 任何更新操作都会清空整个表的缓存!
UPDATE product SET price = 99 WHERE id = 1; -- ❌ 整表缓存失效
-- 下一个查询又要重新查
SELECT * FROM product WHERE id = 1; -- ❌ 缓存未命中,重新执行
graph LR
A[写入缓存] --> B[任何UPDATE/INSERT/DELETE]
B --> C[缓存失效]
C --> D[重新查询]
D --> A
E[循环:对写频繁的表<br/>缓存几乎永远不生效]
问题二:缓存粒度太粗
-- 以下两条完全不同,无法复用缓存
SELECT * FROM user WHERE id = 1; -- 缓存key: select * from user where id = 1
SELECT * FROM user WHERE id = 2; -- 缓存key: select * from user where id = 2
-- 连空格不同都算不同查询
SELECT * FROM user WHERE id =1; -- 缓存key不同!
查询缓存基于精确字符串匹配,任何字符差异都导致缓存 miss。
问题三:缓存管理有开销
sequenceDiagram
participant Q as 查询
participant QC as 查询缓存
participant T as 表数据
Q->>QC: 检查缓存(加锁)
QC-->>Q: 命中/未命中
QC-->>QC: ⭐ 缓存查找本身有锁开销
T->>QC: UPDATE 清空缓存
Note over QC: ⭐ 清空操作也需要排他锁<br/>高并发下锁竞争严重
缓存互斥:在检查缓存时,MySQL 需要加锁,这在高并发下是一个严重的性能瓶颈。
问题四:对写密集型场景是灾难
| 场景 | 查询缓存效果 |
|---|---|
| 只读(配置表) | ✅ 效果好 |
| 读写比 10:1 | ⚠️ 效果一般 |
| 读写比 1:1 | ❌ 负面效果 |
| 写多于读 | ❌ 严重负面 |
对写频繁的表,每次写入都要清空缓存,而清空操作需要独占缓存锁,写操作越多,锁竞争越激烈,性能反而下降。
官方测试数据
MySQL 官方在 8.0 发布时公布的数据:
在典型的高并发 OLTP 场景中,启用查询缓存的性能比禁用还差 10-30%。
替代方案
1. 应用层缓存(推荐)
# 使用 Redis/Memcached 在应用层缓存
def get_user(user_id):
cache_key = f"user:{user_id}"
user = redis.get(cache_key)
if user:
return json.loads(user)
user = db.query("SELECT * FROM user WHERE id = %s", user_id)
redis.setex(cache_key, 3600, json.dumps(user))
return user
2. MySQL 8.0 内置缓存替代
-- 8.0 弃用查询缓存,但提供了:
-- 1. InnoDB Buffer Pool(数据页缓存)
-- 2. 预编译语句缓存
-- 3. 表缓存
-- 这些比查询缓存高效得多
SET GLOBAL innodb_buffer_pool_size = 4 * 1024 * 1024 * 1024; -- 4GB
面试要点
- 根本原因:收益远小于代价,在写频繁场景甚至导致性能下降
- 失效机制:任何对表的 DML 操作都清空该表所有缓存
- 锁竞争:缓存检查和清空都需要加锁
- 替代方案:应用层 Redis 缓存 + InnoDB Buffer Pool
- 8.0 移除设计:MySQL 团队认为这个特性是”负优化”
一句话总结:查询缓存就像”把水倒进漏水的桶”——不仅没存住,搬桶还费劲。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容