查询缓存为什么被移除
查询缓存(Query Cache)在 MySQL 5.7 就被标记弃用,8.0 被彻底移除:query_cache_type、query_cache_size 等变量与 SQL_CACHE、SQL_NO_CACHE 子句都不再存在。退场原因是失效颗粒度太粗——任何一张表的写入都会让该表在缓存里的所有结果作废,高并发写入下命中率极低却要付出全局锁竞争成本。缓存职责交回应用层、Redis 或代理层。
基本信息
| 适用版本 | MySQL 5.7 可用但已弃用;8.0 完全移除 |
|---|---|
| 判定方式 | 8.0 上 SHOW VARIABLES LIKE 'query_cache%' 返回空集 |
| 历史缺陷 | 全局互斥锁加表级失效,写热点表几乎无收益 |
| 替代方案 | 应用层缓存、Redis、代理层查询缓存、只读副本 |
| 升级影响 | my.cnf 里残留 query_cache_* 参数会导致实例启动失败 |
| MariaDB 差异 | MariaDB 10.x 仍保留查询缓存 |
典型使用场景
- 从 5.7 升级到 8.0 之前做配置兼容盘点
- 接手老系统时判断数据库层还有没有查询缓存可用
- 解释历史上「开了查询缓存反而更慢」的现象
- 设计读多写少接口的缓存方案时界定数据库与缓存的职责边界
- 排查升级后应用报未知系统变量的报错
升级前后检查
升级前后检查
# 5.7 上确认现状:命中率长期为 0 就是该弃用的信号
mysqladmin -uroot -p variables | grep -i query_cache
mysql -uroot -p -e "SHOW STATUS LIKE 'Qcache%';"
# 8.0 上执行:返回空集说明变量已不存在
mysql -uroot -p -e "SHOW VARIABLES LIKE 'query_cache%';"
# 扫配置文件与脚本里的残留参数或子句
grep -rniE 'query_cache|SQL_CACHE|SQL_NO_CACHE' /etc/my.cnf /etc/my.cnf.d/ /opt/app/sql/
# 8.0 上更该关注的读性能指标
mysql -uroot -p -e "SHOW STATUS LIKE 'Innodb_buffer_pool_read%';"
mysql -uroot -p -e "SHOW STATUS LIKE 'Threads_connected';"升级清理清单
| 检查项 | 5.7 里的形态 | 8.0 的处理 |
|---|---|---|
| query_cache_type | 0 / 1 / 2 | 删除该行,否则启动失败 |
| query_cache_size | 常被设成几十 MB | 删除 |
| query_cache_limit | 限制单条结果集大小 | 删除 |
| query_cache_min_res_unit | 内存分配粒度 | 删除 |
| SQL_CACHE / SQL_NO_CACHE | 写在语句或代码里 | 清掉,8.0 不再识别 |
| 监控面板与巡检脚本 | 采集 Qcache_* 指标 | 改采缓冲池命中率等指标 |
查询缓存的历史教训是失效颗粒度:任何写入都会让整张表的结果作废,所以它对写多读少的库几乎没有价值。做应用层或 Redis 缓存时要同样注意键设计与失效粒度,否则会把同一个问题在应用层重演一遍。