navicat默认单条insert+自动提交导致极慢,因每行触发网络往返、日志刷盘、语法解析;应改用扩展插入、手动事务、禁用校验与预览,并优先启用load data/bulk insert。
不是sql写错了,也不是数据库卡了,而是navicat默认用“单条insert + 自动提交”模式在执行,每行都触发一次网络往返、一次日志刷盘、一次语法解析——50000行就是50000次重复劳动。
为什么INSERT INTO t(x) VALUES (1);逐行执行特别慢
Navicat对普通SQL文件(尤其是从“转储SQL”生成的)默认不加事务包装,也不合并语句。它把每一行INSERT当做一个独立请求发给MySQL服务端:
- 每条语句都走完整MySQL协议:建立packet头、发送、等待OK响应,千兆内网下round-trip延迟也至少0.5–2ms,5万次就是25–100秒纯网络开销
- autocommit=1开启时,每条
INSERT强制写redo log并fsync到磁盘,SSD也扛不住高频刷写 - Navicat UI线程同步做语法高亮(ANTLR解析)、结果预览、本地SQLite历史记录写入,CPU常飙到70%+,但实际没在干数据库的事
- 若启用了“执行后刷新表结构”,每插一行还会额外发
SHOW CREATE TABLE等3–5次元数据查询
怎么让INSERT真正跑起来:改格式 + 关校验 + 包事务
核心是绕过Navicat的GUI执行链路,逼近原生命令效率:
- 导出时勾选
Extended Insert Statements(扩展插入),让mysqldump或Navicat“数据传输”生成形如INSERT INTO t VALUES (1),(2),(3);的语句——字段名只写一次,MySQL只需解析一次 - 导入前,在Navicat查询窗口手动加事务控制:
SET autocommit = 0;开头,COMMIT;结尾,把全部INSERT包进一个事务 - 用“运行SQL文件”功能(非右键→运行),取消勾选
执行前验证SQL语法,选快速执行(不返回结果集) - 如果SQL文件含
CREATE TABLE,务必先单独执行建表部分,再导入纯INSERT——避免DDL锁阻塞DML,InnoDB缓冲池也能复用
别信“自动优化”,Navicat不会主动切高速通道
Navicat永远不会因为你导入的是50万行就自动启用LOAD DATA LOCAL INFILE或BULK INSERT——这些必须手动打开:
- 在“数据传输”向导的「高级」页中,明确勾选
Use LOAD DATA(MySQL/MariaDB)或Use BULK INSERT(SQL Server) - 确认目标库已授权:
GRANT FILE ON *.* TO 'user'@'%';(MySQL)或ALTER SERVER ROLE bulkadmin ADD MEMBER [user];(SQL Server) - 跨系统(如macOS连云上MySQL)时,禁用
Use SSL、用IP直连、确保Navicat是Apple Silicon原生版——SSL握手+DNS解析+Rosetta转译三重延迟能把首连拖到5秒
最易被忽略的一点:Navicat的“分批导入”按行数切,不看实际字节数。TEXT/JSON字段密集的表,设Batch size = 10000可能单批超10MB,直接触发内存溢出或超时。先用head -n 1000 data.sql | wc -c估算平均行宽,再反推安全批次大小。











