MySQL source导入大SQL文件卡死本质是单事务导致内存爆满:默认将整个文件当一个事务执行,百万级INSERT使InnoDB undo log和buffer pool撑爆;含CREATE TABLE+大量数据时更严重,因无提交点而卡死;建议禁用mysql -u root -p直接source。
MySQL source 导入大SQL文件卡死,本质是单事务+内存爆满
不是网络慢,也不是磁盘慢,而是默认把整个sql文件当一个事务执行,遇到百万级 insert 时,innodb 的 undo log 和 buffer pool 直接撑爆。尤其当文件含 create table + 大量数据,source 会先建表再逐行插入,没提交点,一卡到底。
实操建议:
- 别用
mysql -u root -p 或 <code>source big.sql—— 这俩都默认无事务分隔 - 提前在SQL文件头部加
SET autocommit=0;,结尾加COMMIT;,但治标不治本,仍可能OOM - 真正有效的做法:用
mysqlimport(纯数据)或拆成带COMMIT的批量INSERT块,每5000–10000行一次提交 - 导入前关掉唯一性检查:
SET unique_checks=0;、关掉外键检查:SET foreign_key_checks=0;,导入完再开
PostgreSQL 用 psql -f 导入慢?试试 COPY 替代 INSERT
PostgreSQL 的 psql -f big.sql 本质是逐条解析执行 SQL,哪怕只是 INSERT,每行都是独立事务(除非显式包在 BEGIN; ... COMMIT; 中),性能比 MySQL 还差。而原生 COPY 是二进制协议直写数据页,快一个数量级。
实操建议:
- 如果原始SQL是
INSERT INTO t VALUES (...),(...);批量格式,用sed或 Python 脚本转成 CSV,再用COPY t FROM '/path/to/data.csv' WITH (format csv); - 确保 CSV 字段顺序、NULL 表示(
\N)、引号规则和目标表一致,否则报错invalid input syntax for type X - 导入前执行
SET synchronous_commit = off;和SET maintenance_work_mem = '2GB';(根据内存调),能显著提速 - 避免在
COPY过程中做索引维护:先删索引,导入完重建
SQLite 导入超 100MB SQL 文件卡住?关掉 journal_mode + 分文件更稳
SQLite 默认用 DELETE journal mode,每条 INSERT 都要 fsync 日志,IO 成瓶颈;且单个事务过大时,WAL 文件暴涨,容易触发 database is locked 或磁盘满。
实操建议:
- 导入前执行:
PRAGMA journal_mode = OFF;(仅限导入,完事后切回WAL或DELETE) - 用
sqlite3 db.sqlite <script.sql> 前,先加 <code>PRAGMA synchronous = OFF;和PRAGMA cache_size = 10000; - 用
split -l 5000 script.sql chunk_拆文件,再循环执行:for f in chunk_*; do sqlite3 db.sqlite - 如果脚本含大量重复
INSERT,改用INSERT OR IGNORE或INSERT OR REPLACE,避免约束冲突中断流程
通用分批逻辑怎么写?别手写循环,用现成工具链
自己写 Python 读SQL、切 INSERT、拼事务,容易漏掉注释、引号嵌套、多行语句,反而引入 bug。成熟场景优先用管道组合已有工具。
实操建议:
- Linux 下用
sed -n '/^INSERT /,/^;/p' big.sql | split -l 10000 - insert_batch_提取并切分 INSERT 块(注意适配你的SQL风格) - 用
awk '/^INSERT/{i++} {print > "batch_" int((i-1)/5000) ".sql"}' big.sql按 INSERT 条数分片(更准,但需预处理去注释) - Python 小脚本推荐用
sqlparse库解析,而不是正则匹配:sqlparse.split(sql_content)能正确识别语句边界 - 无论哪种分法,每个子文件开头加
BEGIN;,结尾加COMMIT;,并确保不含CREATE INDEX等 DDL——DDL 不能跨事务
真正难的不是“怎么分”,而是判断哪部分该分、哪部分必须原子执行。比如建表+初始化配置必须一起,而用户数据可以拆。混在一起分,轻则主键冲突,重则约束失效。这点容易被跳过。


















