mysql 8.0 已彻底移除查询缓存,相关参数(如 query_cache_type、query_cache_size)被忽略或报错;连接层无内置“连接缓存”,需依赖应用层连接池或 tcp keepalive;核心缓存机制是 innodb 缓冲池,应合理配置 innodb_buffer_pool_size 并配合应用层 redis 等外部缓存。

MySQL 8.0 已彻底移除查询缓存(query_cache_type、query_cache_size 等所有相关参数),启用会报错或静默忽略;连接层也没有“连接缓存”这个内置机制——所谓“连接缓存”通常指应用层复用连接(如连接池),或内核级的 TCP 连接复用(keepalive),而非 MySQL Server 自身配置项。
为什么 query_cache_type=1 不生效或启动失败
MySQL 5.7 是最后一个支持查询缓存的大版本,且默认已禁用;升级到 8.0 后,任何尝试设置 query_cache_size 的行为都会被忽略,错误日志中可能出现警告:[Warning] 'query_cache_type' is deprecated and will be removed in a future release.。即使强行写入配置文件,mysqld 也不会加载这些参数,更不会分配内存。
- 5.7 中开启需同时设
query_cache_type=1且query_cache_size>0(如16M) - 查询缓存仅对完全一致的文本 SQL 生效(区分大小写、空格、注释),且表一更新整个缓存就失效,实际命中率极低
- 在高并发写场景下,缓存锁争用反而成为性能瓶颈,官方弃用正是基于此
替代方案:用 innodb_buffer_pool_size 缓存数据页
真正影响查询性能的是 InnoDB 缓冲池——它缓存的是磁盘上的数据页和索引页,不是 SQL 文本结果。这是当前 MySQL 最核心的缓存机制。
- 建议设为物理内存的 50%–75%,但不要超过
innodb_buffer_pool_size上限(如 128G 物理内存可设80G) - 若实例有多个 buffer pool 实例(
innodb_buffer_pool_instances>1),需确保总大小能被整除,否则多余内存不被使用 - 动态调整需满足条件:MySQL 5.7+ 支持在线扩容/缩容,但只能以
innodb_buffer_pool_chunk_size × innodb_buffer_pool_instances为单位增减
如何减少连接开销:靠应用层连接池,不是 MySQL 配置
MySQL 本身没有“连接缓存”开关。所谓“快速复用连接”,必须由客户端实现:
- Java 应用用 HikariCP、Druid,Python 用
mysql-connector-python的pool_size或 SQLAlchemy 的QueuePool - 避免每次请求都
connect()+close(),连接池能复用已认证的连接,省去握手、权限校验开销 - MySQL 端只需合理设
wait_timeout(默认 28800 秒)和max_connections(如500),防止空闲连接长期占用资源或突发连接打满上限
其他有效缓存手段:从查询和架构入手
绕过 MySQL 层做缓存,往往比依赖其内置机制更可控、更高效:
- 应用层加 Redis 缓存热点查询结果(如用户资料、商品详情),用
SET user:123 "{...}" EX 300控制 TTL - 对频繁聚合的报表类查询,预计算结果写入汇总表(
summary_daily_sales),用定时任务刷新 - 用
select SQL_NO_CACHE ...或SELECT SQL_CACHE ...已无意义(8.0 不识别),别再写进代码里
真正要调的不是“缓存开关”,而是缓冲池大小、连接池策略、以及是否把不该走 MySQL 的读请求提前拦截掉——这些地方出问题,配再多“缓存参数”也没用。