myisam索引缓存上限需综合平台限制、索引总大小和可用内存三者确定:32位系统≤2g,64位系统建议≤4g;安全值为myisam索引总大小×1.1,且须预留innodb缓冲池、会话缓冲及os内存;命中率>99%后扩容无效。

MyISAM索引缓存上限不能只看物理内存百分比,必须结合索引总大小、系统预留内存和平台限制三者交叉验证,否则极易导致OOM或浪费。
key_buffer_size 的硬性平台限制
该参数在 32 位系统上不能超过 2G,64 位系统建议不超过 4G。即使服务器有 128G 内存,也不应突破此上限——MySQL 的 MyISAM 键缓存本身存在内部管理开销,过大反而降低 LRU 效率,且 key_buffer_size 是全局单一块,无法按表隔离。
- 超出
4G后,部分 MySQL 版本(如 5.7 早期)会静默截断为 4G,不报错也不警告 - 若用的是 Percona Server 或 MariaDB,可检查
SHOW VARIABLES LIKE 'key_buffer_size'确认实际生效值
基于 MyISAM 索引实际大小的上限
真正安全的上限是所有 MyISAM 表索引文件(.MYI)的总和,再乘以约 1.1 的冗余系数。直接查 information_schema 比手动 du -sh *.MYI 更准:
SELECT CEILING(SUM(INDEX_LENGTH) * 1.1 / 1024 / 1024) AS `mb_needed`
FROM information_schema.TABLES
WHERE ENGINE = 'MyISAM'
AND TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema');
- 结果若为
320,则key_buffer_size = 384M是合理上限,而非盲目设成2G - 如果返回
0,说明库中已无 MyISAM 表,key_buffer_size设为16M~32M足够应付临时磁盘表
扣除系统和其他 MySQL 组件后的可用内存
不能把所有空闲内存都留给 key_buffer_size。需预留至少:innodb_buffer_pool_size(哪怕不用 InnoDB,也得留出基础空间)、max_connections * (sort_buffer_size + read_buffer_size)、操作系统缓存(至少 2G)。
- 例如:机器 32G 内存,
innodb_buffer_pool_size=16G,max_connections=200,各会话缓冲均设为2M→ 仅会话缓冲就占400M,OS 至少留2G→ 剩余约13.6G可分配,但受平台上限约束,仍只能取4G以内 - 若
Key_reads / Key_read_requests比值长期低于0.01(即命中率 >99%),再往上加key_buffer_size已无收益,此时应优先优化查询或迁移到 InnoDB
真正容易被忽略的是:MyISAM 表一旦混用大量 TEXT/BLOB 字段,其索引块(.MYI)可能远小于数据文件(.MYD),但 INDEX_LENGTH 在 information_schema 中统计准确;而 key_cache_division_limit 和 key_cache_age_threshold 这类高级参数,只有在 key_buffer_size 接近上限且命中率波动明显时才值得动。











