myisam单线程批量导入更快,因其省略事务、行锁、崩溃恢复等机制,仅追加数据并更新索引偏移;但缺乏安全性与并发能力,实际线上应优先调优innodb配置以兼顾性能与可靠性。

MyISAM单线程批量导入确实更快,但几乎不该用。 它快是靠砍掉事务、行锁、崩溃恢复这些“安全带”换来的——你得到的是一个不能在线服务、一崩就可能丢数据、并发查询直接被锁死的表。
MyISAM为什么看起来写得快
不是它真强,而是它省掉了InnoDB必须做的几件事:
-
innodb_flush_log_at_trx_commit = 1被跳过 → 没有每次插入都刷redo log的I/O开销 - 表级锁 → 不用管理行锁队列、MVCC版本链、间隙锁等复杂逻辑
- 无唯一性/外键校验 → 插入时不做索引冲突检查,也不查父表
- 非聚簇索引 → 数据和索引物理分离,插入只需追加+更新索引文件,不触发B+树页分裂
所以用 LOAD DATA INFILE 导入1亿行,MyISAM可能比默认配置的InnoDB快2–3倍。但只要后续要查、要更新、要和其他业务共用这张表,它的锁表行为立刻反噬性能。
InnoDB批量导入慢,其实是配置没对齐场景
真正瓶颈不在引擎本身,而在默认参数面向的是“小事务+强一致性”,不是“大灌入+弱一致性”。关键调优点如下:
- 临时设
innodb_flush_log_at_trx_commit = 2(或0,仅限导入期间)→ 避免每行都刷盘 - 导入前执行
SET UNIQUE_CHECKS = 0和SET FOREIGN_KEY_CHECKS = 0→ 关掉约束校验 - 确保主键有序:源数据先按主键
ORDER BY id,再导入 → 减少页分裂,写入效率可提30%+ - 增大
innodb_buffer_pool_size至物理内存50%~75% → 减少磁盘换页 - 用
INSERT INTO ... VALUES (),(),()...批量插入(每批≤1000行),或直接LOAD DATA INFILE
这些调整做完,InnoDB导入速度能逼近MyISAM,同时保留ACID、行锁、崩溃恢复能力——这才是线上系统真正需要的“快”。
几亿条数据,别只盯着单表写入速度
单表撑不住几亿行:B+树超过3层后,索引查找和写入放大效应明显;MySQL官方推荐单表行数控制在2000万以内。实际落地必须考虑:
- 是否已做分表?比如按时间/用户ID哈希拆成10–100个
INNODB子表 - 是否启用分区?如
PARTITION BY RANGE (created_at),避免单个分区过大 - 导入路径是否绕过网络?
LOAD DATA INFILE要求文件在MySQL服务器本地,否则得用LOAD DATA LOCAL INFILE(需客户端和服务端都开启) - 是否忽略重复?
INSERT IGNORE或ON DUPLICATE KEY UPDATE会显著拖慢速度,离线导入建议先去重再灌
真正卡住几亿数据导入的,往往不是引擎选型,而是没提前规划好表结构层级、没关掉本不该开的校验、或者把数据当“单块石头”硬砸,而不是切成可并行的小批次流式处理。











