mysql 8.0.3起彻底移除query_cache_*变量及sql_cache/sql_no_cache语法,配置残留将导致启动失败;缓存失效粒度为表级且引发全局锁,实际性能收益极低;应聚焦调优innodb_buffer_pool_size并优化索引。

MySQL 8.0 启动报 Unknown system variable 'query_cache_type' 是正常现象
这不是配置写错了,是变量真没了。从 MySQL 8.0.3 开始,所有 query_cache_* 相关变量(query_cache_type、query_cache_size、query_cache_limit)已被从源码中彻底删除。my.cnf 里哪怕只保留一行 query_cache_type = 0,mysqld 启动时就会报错并退出。Percona Server 8.x、MariaDB 10.6+ 同样不识别这些配置项。升级前必须手动清空所有以 query_cache_ 开头的行,否则服务起不来。
SELECT SQL_CACHE 在 MySQL 8.0 中直接语法报错
这条语句在 8.0 中已完全失效:ERROR 1286 (42000): Unknown table engine 'QUERY CACHE'。它不是被忽略,而是解析器根本不再认识这个 hint。同样,SQL_NO_CACHE 也无效。如果你在迁移脚本或 ORM 配置里还留着这类 hint,它们只会污染 SQL 可读性,对执行无任何影响,建议一并清理。
缓存失效不是“偶尔清空”,而是每次写操作都触发表级广播
Query Cache 的失效粒度是整张表:只要对 users 表执行一次 UPDATE users SET name = 'x' WHERE id = 1,所有命中过该表的查询——包括 SELECT COUNT(*) FROM users、SELECT * FROM users WHERE status = 'active'、SELECT id, email FROM users LIMIT 1——全部立即失效。更糟的是,这个清空过程本身也要抢 LOCK_query_cache 全局锁,导致并发 SELECT 全部排队等待。在真实 OLTP 场景中,缓存刚写入就因一次日志 INSERT 被清掉,根本热不起来。
别再调 query_cache_size,去调 innodb_buffer_pool_size
真正影响重复查询性能的,从来不是 Query Cache,而是 InnoDB 缓冲池。它缓的是数据页,复用率高、无全局锁、支持 LRU-K 自适应淘汰。实操建议:
-
innodb_buffer_pool_size设为物理内存的 60%–75%,切勿超可用内存,否则触发 swap - 大于 1GB 时,启用多实例:
innodb_buffer_pool_instances = 8,减少内部争用 - 监控
Buffer pool hit rate,持续低于 95% 就说明不够用 - 配合覆盖索引(如
SELECT id, name FROM users WHERE id = ?加索引(id, name)),让查询完全走内存页,比任何结果缓存都快且稳
Query Cache 的幽灵还在不少旧配置模板里游荡。删干净它,系统反而更轻、更稳、更容易诊断——尤其是当你的慢查根源其实是 buffer pool 不够、索引缺失,而不是“缓存没开”。











