<p>MySQL 8.0 彻底删除了全局 Query Cache 模块,而非仅禁用或针对 MyISAM;其源码中已移除所有 querycache* 变量及逻辑,启动时遇相关配置即报错退出,须清理配置文件并转向 InnoDB 缓冲池、索引优化及应用层缓存。</p>

Query Cache 不是 MyISAM 的功能,也不是 MySQL 8.0 “删除了 MyISAM 的查询缓存”——它从来就不是按存储引擎划分的模块。MySQL 5.7 及更早版本中,Query Cache 是一个**全局、独立于存储引擎的 Server 层模块**,无论你用的是 MyISAM 还是 InnoDB,只要 SQL 满足条件(纯 SELECT、无动态函数、字节级一致等),都走同一套缓存逻辑。
MySQL 8.0 做的事,是把整个 Query Cache 模块从源码里物理删除,连带所有相关变量:query_cache_type、query_cache_size、query_cache_limit 全都不再识别。这不是“针对 MyISAM 做了什么”,而是彻底砍掉了这个设计过时、高并发下反拖慢性能的组件。
MySQL 8.0 启动报 Unknown system variable 'query_cache_type' 怎么办
这不是配置写错,是变量已不存在。mysqld 解析器在启动时根本找不到这个符号,直接拒绝加载配置并退出。
- 必须手动删掉
my.cnf(或my.ini)里所有以query_cache_开头的行,包括注释掉的也得清理干净 - Percona Server 8.x、MariaDB 10.6+ 同样不兼容,别指望降级或兼容开关
- Docker 镜像或云数据库(如 RDS)若复用旧参数组,也会卡在这一步,需同步更新配置模板
为什么 UPDATE 一行就清空整张表所有缓存
Query Cache 的失效粒度是表级(table-level),且不区分 DML 影响范围。哪怕只执行 UPDATE users SET name='x' WHERE id=123,所有命中 users 表的缓存条目——不管 SQL 多具体、是否带 LIMIT、是否只查一个字段——全部被立即清除。
- 清空动作本身还要抢全局锁
LOCK_query_cache,期间所有新查询排队等待 - 事务未提交时缓存已失效,但新查询又不能读未提交数据,形成“失效了却还不能用”的真空
- 分区表默认禁用
Query Cache,而生产环境大表基本都分区,说明该机制早已脱离主流用法
缓存命中率低到 0.1% 还在吃资源,为什么
命中条件苛刻到几乎不可用:SQL 必须字节级完全一致,且大量常见语句被跳过。
-
SELECT id FROM t WHERE x=1和SELECT id FROM t WHERE x = 1(空格差一点)就是两个 key - 预处理语句(
PREPARE/EXECUTE)、含NOW()、RAND()、用户变量、子查询、视图的查询,一律不进缓存路径 - 内存按
query_cache_min_res_unit(默认 4KB)硬切,缓存结果集仅 1KB 也要占 4KB,碎片严重时FLUSH QUERY CACHE自身就要持锁、吃 CPU
innodb_buffer_pool_size、索引覆盖、自适应哈希,以及应用层可控的缓存策略。


















