key_buffer_size 是 MySQL 专用于缓存 MyISAM 表索引块的全局内存缓冲区,仅对 MyISAM 有效,InnoDB 使用 innodb_buffer_pool_size;需根据 MyISAM 索引总大小(information_schema.TABLES 中 index_length 总和)设为 80%~90%,且必须配置在 [mysqld] 段下、单位大写无空格、修改后重启生效。

key_buffer_size 是干啥的,只对 MyISAM 有效
key_buffer_size 是 MySQL 中专用于缓存 MyISAM 表索引块的内存区域。它不作用于 InnoDB 表——InnoDB 用的是 innodb_buffer_pool_size。如果你的库已全面迁到 InnoDB(现在绝大多数都是),调这个值基本没效果,甚至可能浪费内存。
常见错误现象:SHOW STATUS LIKE 'Key%'; 显示 Key_reads 很高、Key_read_requests 很低,说明索引块频繁从磁盘读取,缓存命中率差;但若引擎是 InnoDB,这问题跟 key_buffer_size 无关,别在这儿瞎调。
- 只在启用 MyISAM 表时才需关注,检查方式:
SELECT ENGINE, COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys') GROUP BY ENGINE; - 默认值通常极小(8MB 或 16MB),远低于实际需求
- 不能超过操作系统能给单个进程分配的物理内存上限,否则触发 swap,性能断崖下跌
怎么设一个靠谱的 key_buffer_size 值
不是拍脑袋填个 512M 就行。得看真实索引体积 + 并发访问压力。MyISAM 索引文件(.MYI)总大小是硬指标——key_buffer_size 超过它太多纯属冗余;略小于它(比如 80%~90%)反而更稳,留点空间给 OS 缓存和连接线程。
实操建议:
- 查所有 MyISAM 表索引总大小:
SELECT SUM(index_length) FROM information_schema.TABLES WHERE ENGINE='MyISAM' AND TABLE_SCHEMA NOT IN ('mysql','information_schema');结果单位是字节,除以 1024/1024 得 MB - 初始设为索引总大小的 80%,例如算出来是 320MB,就配
key_buffer_size = 256M - 上线后观察
Key_cache_miss_rate = Key_reads / Key_read_requests,持续高于 0.01(即 1%)说明不够;低于 0.001 可考虑微降 - 避免设成 2G、4G 这种整数——容易和系统其他内存争抢,用 1984M、3840M 这类“非整”值反而更安全
my.cnf 里写错位置或格式会直接失效
key_buffer_size 必须放在 [mysqld] 段下,且只能是全局配置项,不能按数据库或表设置。写错位置(比如塞进 [client])、拼错名字(如 key_buffer 少了 _size)、单位写错(512MB 写成 512mb 或漏掉单位)都会导致 MySQL 启动时静默忽略该配置,仍用默认值。
验证是否生效最简单的方法:mysql -e "SHOW VARIABLES LIKE 'key_buffer_size';",输出值必须和配置文件里写的完全一致(注意单位换算)。如果显示 8388608,那就是 8MB,默认值,说明没加载成功。
- 单位只认
K/M/G(大写),512m或512MB都不合法 - 值不能带空格:
key_buffer_size = 256 M❌,key_buffer_size = 256M✅ - 修改后必须重启 MySQL(不是 reload),因为这是启动时分配的全局缓冲区
和 query_cache_size 混用会互相拖累
MySQL 5.7 及以前,有人习惯把 key_buffer_size 和 query_cache_size 一起调大。但这两者共享同一片内存管理逻辑,且 query cache 在高并发更新场景下锁竞争严重。当 query_cache_size > 0 时,哪怕只设 1MB,也会显著增加 key_buffer 的管理开销,导致索引缓存效率下降。
如果你还在用老版本且无法关 query cache,至少做到:
- 确保
query_cache_type = 0(禁用),而不是只设query_cache_size = 0 - 若必须开启 query cache,
key_buffer_size不宜超过 512M,否则内存碎片和锁等待会恶化 - MySQL 8.0 已彻底移除 query cache,此时
key_buffer_size的表现更干净,但也意味着你更该确认自己是否真在用 MyISAM
真正麻烦的从来不是设多大,而是忘了自己到底用的是什么引擎——查 ENGINE 比调参重要十倍。一旦误判,所有优化都在给空气调参。










