MySQL 查询缓存(query_cache)已彻底废弃,别再配置它
MySQL 8.0 起已完全移除
query_cache_type、
query_cache_size等所有查询缓存相关参数。即使你在 5.7 中开启,也会因表级变更(如
INSERT/
UPDATE)导致整张表对应的所有缓存失效,实际命中率极低。很多线上服务反而因维护缓存锁造成性能下降。
实操建议:
确认版本:SELECT VERSION();,若 ≥ 8.0,直接忽略 query cache 配置项 5.7 环境下若仍启用,请监控
Qcache_hits与
Qcache_inserts比值,低于 0.2 就该关掉 配置文件中删除或注释掉
query_cache_type=1和
query_cache_size=xxx
InnoDB 缓冲池(innodb_buffer_pool_size)是真正的性能核心
这是 MySQL 最关键的内存缓存机制:它把频繁访问的表数据和索引页缓存在内存中,避免每次查询都读磁盘。它的效果远超旧式 query cache,且由存储引擎自动管理,无需 SQL 层干预。
实操建议:
生产环境建议设为物理内存的 50%–75%,但需预留至少 2GB 给 OS 和其他进程 检查当前使用率:SHOW ENGINE INNODB STATUS\G查看 “Buffer pool hit rate” —— 持续低于 990/1000(即 99%)说明不够用 动态调整(8.0+):
SET GLOBAL innodb_buffer_pool_size = 4294967296;(4GB),但注意该值必须是
innodb_buffer_pool_chunk_size × innodb_buffer_pool_instances的整数倍 避免设得过大导致 swap,可观察
free -h中的
available是否持续低于 1GB
应用层缓存(Redis / Memcached)和 MySQL 协作的关键点
真正提升读性能的主流方案是“MySQL + 应用缓存”,但容易因缓存与数据库不一致导致脏数据。协作不是简单加个
SET,而是要对写操作做精细控制。
实操建议:
读路径:优先查 Redis,未命中再查 MySQL,并将结果SET回缓存(带合理
EXPIRE,如 300 秒) 写路径:必须执行「先删缓存,再更新 DB」或「先更新 DB,再删缓存」——二者选其一并严格统一,禁止只更新不删 高并发写时,删缓存后可能有旧数据回写(cache stampede),可用
SET … NX EX或分布式锁兜底 对主键明确的查询(如
SELECT * FROM user WHERE id = 123),缓存 key 建议设计为
user:123,而非模糊的
user_list类全量缓存
临时表、排序、JOIN 的内存缓存靠 sort_buffer_size 等参数,但别乱调
这类会话级缓存用于加速 ORDER BY、GROUP BY、JOIN 等操作,但它们按连接分配,设太大反而引发内存爆炸,尤其在连接数高的场景。
实操建议:
默认值通常够用:sort_buffer_size(默认 256KB)、
join_buffer_size(默认 256KB)、
read_buffer_size(默认 128KB) 仅当慢日志中出现
Using filesort或
Using temporary且对应 SQL 频繁执行时,才考虑局部调大 绝对不要在全局配置里设成几 MB —— 若有 1000 个连接,就多占几个 GB 内存 更优解是优化 SQL 和索引:比如为
ORDER BY created_at加联合索引
(status, created_at),往往比调 buffer 更有效
真正卡住性能的,常常不是“有没有缓存”,而是“缓存哪一层、怎么失效、谁负责一致性”。InnoDB buffer pool 是基础,应用缓存是杠杆,而错误的 query cache 配置或盲目调大 session buffer,反而会成为隐性瓶颈。
