关闭unique_checks和foreign_key_checks能显著提速,因mysql默认逐行校验唯一性、外键及维护二级索引,百万级数据下开销线性放大;关闭后仅写入主键/聚簇索引,导入完再批量重建索引,效率提升3–5倍。

直接关掉 unique_checks 和 foreign_key_checks 能显著提速,但必须配合事务包裹和后续恢复,否则数据可能不一致。
为什么关掉索引和外键检查能快这么多
MySQL 在每条 INSERT 执行时,默认会实时校验唯一性、检查外键引用是否合法,并维护二级索引。对百万级以上数据,这些操作不是“一次建好”,而是逐行触发,开销呈线性放大。关掉后,InnoDB 只做最基础的主键/聚簇索引写入,等全部插入完再一次性重建索引,效率提升常达 3–5 倍。
注意:foreign_key_checks=0 不影响主键或唯一约束本身,只跳过外键引用校验;unique_checks=0 也不禁用唯一索引,只是暂不检查冲突——所以导入前必须确保源数据本身无重复或非法外键值。
导入时怎么安全地关闭并恢复
不能只在客户端执行 SET,因为 mysqldump 生成的 SQL 文件里自带 CREATE TABLE 和 INSERT,需要让这些语句在关闭状态下执行。推荐用管道方式注入控制语句:
mysql -u root -p dbname
-
autocommit=0是必须的,否则每个INSERT都自动提交,关检查就失去意义 -
SOURCE必须在同一个连接中执行,不能拆成两个命令 - 恢复检查后一定要
COMMIT,否则事务未结束,可能锁表或阻塞其他操作
容易被忽略的配套动作
单关检查还不够,这几个点不处理,速度依然卡在瓶颈上:
- 确保 dump 文件用了
--extended-insert(默认开启),避免百万行变成百万条单行INSERT - 导入前临时调低
innodb_flush_log_at_trx_commit到0,减少日志刷盘频率;导入完记得改回1 - 如果 dump 文件含
DROP TABLE或CREATE TABLE,加上--skip-add-drop-table可省掉反复删建表的 I/O -
LOAD DATA INFILE比任何 SQL 导入都快,只要能把 dump 转成 CSV + 表结构单独建好,就该切过去
真正慢的从来不是磁盘读,而是每行都触发的校验、日志、索引更新。关检查只是第一步,后面那几个参数和流程衔接没跟上,等于只拧松了螺丝却没卸下整个轮子。











