key_buffer_size是MySQL专用于缓存MyISAM索引块(.MYI)的全局静态内存参数,仅对MyISAM有效;它不缓存数据(.MYD仍走磁盘),但索引命中可大幅减少Key_reads磁盘I/O,从而提升读取速度;默认8M通常不足,需根据索引实际大小设为1.2–1.5倍并重启生效,同时配套调优read_buffer_size、table_open_cache等参数,并验证命中率≥0.999。

key_buffer_size 不是“开个开关就能提速”,它必须设对、配齐、验证,否则调了也白调。
key_buffer_size 是什么,为什么它决定 MyISAM 读取速度
MyISAM 不用 innodb_buffer_pool_size,它靠 key_buffer_size 缓存索引块(.MYI 文件),数据文件(.MYD)仍走磁盘。只要索引能从内存命中,定位行就快得多——这是 MyISAM 读性能的瓶颈所在。
默认值通常是 8388608(即 8M),对任何稍有规模的 MyISAM 表都远远不够。缓存不足时,Key_reads 会飙升,意味着每次查索引都在读磁盘。
该参数是全局、静态的,修改后必须重启 MySQL 才生效;它只缓存索引,不缓存数据;数据读取仍依赖操作系统页缓存或 read_buffer_size。
怎么设合理的 key_buffer_size 值
不能拍脑袋填百分比。先看当前负载和内存余量:
- 执行
SHOW VARIABLES LIKE 'key_buffer_size';查当前值 - 执行
SHOW STATUS LIKE 'Key_read%';,计算缓存命中率:1 - (Key_reads / Key_read_requests);低于0.999(即Key_reads / Key_read_requests > 0.001)就说明不够 - 用
free -h确认系统空闲内存,留至少 2G 给 OS 和其他进程 - 若 MyISAM 是主力引擎,且总索引大小在 2GB 以内,可设为物理内存的 20%~25%;例如 32G 内存机器,设
key_buffer_size = 6G
配置位置:编辑 /etc/my.cnf 或 /etc/mysql/my.cnf,在 [mysqld] 段下添加:key_buffer_size = 6G
然后重启服务:sudo systemctl restart mysql。
容易被忽略的配套参数
单调 key_buffer_size 不够,MyISAM 读取还卡在其它环节:
-
read_buffer_size:影响全表扫描速度,每个线程独占,建议设为512K~2M(勿超4M,否则高并发时内存爆炸) -
table_open_cache:MyISAM 表打开开销大,若频繁访问上百张 MyISAM 表,需调高(如2000),避免反复打开 .MYI 文件 -
sort_buffer_size:影响ORDER BY、GROUP BY性能,但它是 per-connection 的,设太大反而挤占内存,256K~1M较稳妥 -
query_cache_type = 0:MyISAM 表一旦有写入,整个表的查询缓存全失效,反而拖慢读——尤其在读写混合场景
验证是否真的变快了
重启后别急着上线,先验证三件事:
- 确认新值已加载:
SHOW VARIABLES LIKE 'key_buffer_size';输出应与配置一致 - 观察缓存使用水位:
SHOW STATUS LIKE 'Key_blocks_used';和Key_blocks_unused,两者差值越大,说明实际使用越充分 - 压测典型查询,对比
Key_reads是否明显下降;如果Key_reads / Key_read_requests仍高于0.001,说明要么索引设计不合理,要么key_buffer_size还不够,或者有大量冷查询打穿缓存
真正起效的不是单个参数,而是 key_buffer_size + 合理索引 + 配套缓冲 + 关闭干扰项这一整套组合;其中最容易被跳过的,是验证缓存命中率和关闭查询缓存。


















