innodb缓冲池大小应设为物理内存的50%–75%,且为128mb整数倍;连接数需按峰值加20%余量配置,并与wait_timeout协同;query_cache_type必须关闭;sort_buffer_size等会话级参数勿盲目调大,应基于慢日志和执行计划精准优化。

innodb_buffer_pool_size 设多少才不拖慢查询
这个值决定 MySQL 能把多少数据和索引常驻内存,直接决定 80% 的读性能。设小了,频繁磁盘 IO;设大了,可能挤占系统其他进程内存,触发 OOM Killer 杀掉 mysqld。
- 生产环境建议设为物理内存的 50%–75%,但
innodb_buffer_pool_size必须是 128MB 的整数倍(否则启动报错Invalid value for innodb_buffer_pool_size) - 如果机器总内存 32GB,可设
innodb_buffer_pool_size = 24G;但若同时跑 Redis 或 Java 应用,得留足至少 6GB 给它们 - 不要盲目设到 90%,Linux 内核、文件系统缓存、连接线程栈都需要内存,
top看%MEM持续超 95% 就危险了
max_connections 和 wait_timeout 配合不好会爆连接
连接数不是越多越好。设太高,每个连接吃内存(尤其用了大量临时表或排序),还容易被慢查询拖垮;设太低,应用报 Too many connections。
- 先查真实峰值:
SHOW GLOBAL STATUS LIKE 'Threads_connected';,再加 20% 余量作为max_connections -
wait_timeout(默认 28800 秒)必须配合应用连接池设置。Spring Boot 默认 HikariCPconnection-timeout=30000,那wait_timeout建议设成 60,避免连接池复用“半死”连接导致MySQL server has gone away - 注意:
interactive_timeout控制交互式客户端(如 mysql 命令行),一般和wait_timeout设成一样,否则容易混淆
query_cache_type 关掉就对了
MySQL 5.7 默认已弃用 query cache,8.0 直接删了。但很多老配置还留着 query_cache_type = 1,反而引发锁争用——每次写操作都要清空整个 cache,高并发下性能反降。
- 确认是否启用:
SHOW VARIABLES LIKE 'query_cache_type';,如果是 ON,立刻在my.cnf中加query_cache_type = 0 - 别信“我只读库”,只要从库有
INSERT/UPDATE/DELETE(比如双主、逻辑订阅),query cache 就是负优化 - 替代方案是用应用层缓存(Redis)或代理层缓存(ProxySQL),粒度可控,不污染 MySQL 内核路径
sort_buffer_size 和 read_rnd_buffer_size 别乱调大
这两个是**每个连接独占**的内存,不是全局共享。设成 4M 看似不大,但 500 个连接就吃掉 2GB 内存,且大部分时候根本用不满。
- 默认值(
sort_buffer_size = 256K,read_rnd_buffer_size = 256K)对多数 OLTP 场景足够;只有明确存在Using filesort且排序数据量巨大时才考虑上调 - 调大前先用
EXPLAIN FORMAT=JSON确认是否真卡在排序阶段,而不是索引没建好 - 切忌在
my.cnf里写sort_buffer_size = 8M—— 这会让所有连接都预分配 8MB,不如让应用在必要时用SET SESSION sort_buffer_size = 4M;临时调整
slow_query_log 和 SHOW ENGINE INNODB STATUS\G 出发,而不是照搬网上“最佳配置”。一个参数改错,可能让吞吐跌一半,而你还在查是不是网络问题。











