DELAY_KEY_WRITE是MyISAM表的索引延迟写入机制:更新时仅缓存索引变更到内存key buffer,待表关闭时批量落盘,减少随机I/O提升性能;但异常崩溃会导致索引损坏,必须配合--myisam-recover启动选项启用自动修复。

DELAY_KEY_WRITE 是什么,为什么能提速
DELAY_KEY_WRITE 不是“开启延迟写入”的开关,而是让 MyISAM 在更新数据时跳过实时刷索引到磁盘的动作,只把索引变更暂存在内存的 key buffer 中,等表被关闭(比如 FLUSH TABLES 或缓存淘汰触发)时才批量落盘。这省去了大量随机 I/O,对频繁 UPDATE 或 INSERT 的大表效果明显。
但代价很实在:如果 MySQL 异常崩溃或断电,这部分未刷盘的索引就丢了,下次启动时表可能报错、查询结果错乱,必须靠修复才能恢复一致性。
如何为单个表启用 DELAY_KEY_WRITE
有两种方式,推荐用 ALTER TABLE,不用改建表逻辑:
-
ALTER TABLE table_name DELAY_KEY_WRITE = 1;—— 立即生效,无需重建表 - 建表时加选项:
CREATE TABLE t (id INT) ENGINE=MyISAM DELAY_KEY_WRITE=1;
执行后不会立刻看到性能变化,它只在后续有索引变更的操作中起效。你可以用 SHOW CREATE TABLE table_name; 确认输出里是否含 DELAY_KEY_WRITE=1。
全局配置 delay_key_write 参数必须设为 on 或 ALL
光给表加 DELAY_KEY_WRITE=1 不够,MySQL 还要看全局变量 delay_key_write 的值:
-
SET GLOBAL delay_key_write = 'ON';—— 只对显式声明了DELAY_KEY_WRITE=1的表生效 -
SET GLOBAL delay_key_write = 'ALL';—— 所有 MyISAM 表都强制延迟索引写入(含没声明的) -
SET GLOBAL delay_key_write = 'OFF';—— 全局禁用,哪怕表定义里写了也无效
这个变量不能动态写进 my.cnf 后 reload 生效,必须重启 MySQL 或用 SET GLOBAL;但生产环境建议写进配置文件并重启,避免服务重启后丢失设置。
不配 --myisam-recover 就别用 DELAY_KEY_WRITE
这是最容易被跳过的致命环节。只要开了 DELAY_KEY_WRITE,就必须确保 MySQL 启动时自动检查并修复 MyISAM 表,否则一次意外宕机就可能导致索引损坏且无法察觉。
在 my.cnf 的 [mysqld] 段加上:
myisam-recover=FORCE,BACKUP
或者启动命令行加 --myisam-recover=FORCE,BACKUP。不配这个,等于裸奔——你不是在提速,是在攒故障。
另外,INSERT DELAYED 已在 MySQL 5.6+ 被彻底移除,别再查文档里找它;LOW_PRIORITY 是读写优先级调度,和索引延迟无关,别混用。


















