disable keys仅对myisam表生效,用于禁用非唯一索引更新以批量插入后统一重建;innodb不支持该命令,需改用按主键排序插入、set unique_checks=0、set autocommit=0等优化方式。

因为索引不是“免费的加速器”,而是每次写入都要同步维护的数据结构;关闭索引检查能跳过逐条更新索引树的过程,把索引重建推迟到批量插入完成之后统一做,从而大幅降低 I/O 和 CPU 开销。
DISABLE KEYS 只对 MyISAM 表生效
这是最容易踩的坑:MySQL 的 ALTER TABLE ... DISABLE KEYS 命令仅作用于 MyISAM 存储引擎。它会临时禁用非唯一索引(主键和唯一索引仍受约束),后续插入时跳过索引更新,直到执行 ENABLE KEYS 才一次性重建所有非唯一索引。
InnoDB 表不支持该命令——它没有“禁用索引”机制,强行执行不会报错但也不起作用。InnoDB 的优化方式完全不同:
- 确保数据按主键顺序插入(避免页分裂)
- 关闭自动提交:
SET autocommit = 0,用显式COMMIT批量提交 - 调大
innodb_buffer_pool_size和innodb_log_file_size - 临时关闭唯一性检查:
SET unique_checks = 0(注意:仅适用于确认无冲突数据)
为什么 ENABLE KEYS 耗时可能比插入还长
执行 ENABLE KEYS 时,MyISAM 并不是“打开开关”那么简单,而是要从头构建 B+ 树索引文件。这个过程是单线程、全表扫描式的排序建索引,I/O 密集且不可中断。
常见现象包括:
- 插入 100 万行只用了 40 秒,
ENABLE KEYS却卡了 90 秒 - 期间
SHOW PROCESSLIST显示状态为Repair by sorting - 磁盘写入速率飙升,
iostat -x 1观察到 %util 接近 100%
这不是失败,是正常行为。但如果你在业务高峰期执行,可能引发雪崩——务必安排在低峰期,并预留足够磁盘空间(索引文件可能临时膨胀至原数据 1.5 倍大小)。
INNODB 表想提速,别碰 DISABLE KEYS
对 InnoDB 表误用 DISABLE KEYS 不会报错,但也不会生效,徒增误导。真正有效的做法是组合以下参数:
-
SET unique_checks = 0:跳过唯一索引重复校验(风险可控,导入前确保数据无冲突) -
SET foreign_key_checks = 0:跳过外键约束检查(仅当表无外键依赖时可用) -
SET autocommit = 0+ 每 10k 行COMMIT:避免事务日志过大导致刷盘阻塞 - 用
LOAD DATA INFILE替代INSERT:底层绕过 SQL 解析层,快 5–10 倍
特别注意:unique_checks = 0 关闭后,如果数据实际存在重复,后续开启时不会自动修复,而是在下次插入/更新触发冲突时才报错。它只省去“检查”动作,不省去“写入索引”动作。
真正关键的不是“关不关索引”,而是理解存储引擎如何组织数据——MyISAM 把索引和数据物理分离,所以能批量建索引;InnoDB 的聚簇索引让数据和主键强绑定,任何写入都绕不开 B+ 树维护。选错策略,轻则白忙,重则锁表数分钟。











