disable keys仅对myisam生效,innodb不支持且执行会报错;myisam通过禁用非唯一索引实现批量插入后统一重建,innodb需删辅助索引+关校验+按主键排序插入。

因为索引不是“免费加速器”,而是每次写入都必须同步更新的数据结构;关闭索引检查本质是跳过逐条维护 B+ 树的过程,把开销集中到批量完成后再统一重建。
DISABLE KEYS 只对 MyISAM 表生效,InnoDB 完全不认这个命令
执行 ALTER TABLE t DISABLE KEYS 时,MyISAM 会临时停用所有非唯一索引(主键和唯一索引仍强制校验),后续插入跳过索引更新,直到 ENABLE KEYS 才触发一次性排序建树。而 InnoDB 表执行该语句会直接报错:ERROR 1031 (HY000): Table storage engine for 't' doesn't have this option。误以为“没报错=生效”是高频误区——InnoDB 压根不支持该机制,强行执行等于白忙。
InnoDB 真正有效的“关索引”等效操作是删索引 + 重建
对 InnoDB 表想获得类似效果,必须手动干预索引生命周期:
- 插入前用
DROP INDEX idx_name ON t删除非主键、非外键依赖的辅助索引(主键和唯一约束不能删,否则插入会因校验失败而中止) - 批量插入完成后,再用
CREATE INDEX idx_name ON t(col)重建(MySQL 5.7+ 支持 online DDL,但重建仍比边写边更新快得多) - 配合
SET unique_checks = 0和SET foreign_key_checks = 0,跳过重复和外键校验(仅限可信数据源) - 务必确保数据按主键顺序插入——避免页分裂导致的随机写放大
ENABLE KEYS 或 CREATE INDEX 耗时可能远超插入本身
这是最容易被忽略的代价:
- MyISAM 的
ENABLE KEYS不是开关切换,而是全表扫描 + 排序 + 单线程构建 B+ 树,I/O 密集且不可中断;实测插入 100 万行耗时 40 秒,ENABLE KEYS却卡住 90 秒很常见 - InnoDB 的
CREATE INDEX虽支持并发构建(8.0+),但仍需大量磁盘空间(临时索引文件可达原数据 1.5 倍大小)和 CPU - 两者都会让
SHOW PROCESSLIST显示Repair by sorting或Creating index,期间表不可写,且可能拖垮磁盘利用率(iostat -x 1观察到 %util 接近 100%)
真正关键的不是“能不能关索引”,而是你是否清楚:关的是哪类索引、引擎是否支持、重建成本能否承受、以及业务能否容忍重建期间的锁表或资源争抢。











