Navicat 17 数据传输慢的根源是默认全量缓存、单线程拉取和强校验机制;调低内存限制至128MB、禁用结构校验、改用MySQL Native驱动可提效3–5倍。

Navicat 17 数据传输(尤其是跨库或跨实例的「数据传输」功能)慢,根本不是网络带宽问题,而是它默认启用全量缓存 + 单线程拉取 + 强校验机制,遇到大表(>100MB)就会卡在“正在读取源数据”或“正在写入目标表”。调低缓冲区、禁用校验、换驱动,三步能提效 3–5 倍。
Navicat 17「数据传输」卡在“正在读取源数据”
这不是 MySQL 慢,是 Navicat 自己把整张表 SELECT 结果全加载进内存再分发——哪怕你只传 10 万行,它也试图缓存全部结果集。现象是 CPU 占用低、磁盘 I/O 持续 100%、界面假死,且 max_allowed_packet 调再大也没用。
- 必须进
工具 → 选项 → 数据传输,把「内存使用限制」从默认 1024 改为128(单位 MB) - 取消勾选「验证源/目标表结构一致性」——这个校验会额外执行多次
SHOW CREATE TABLE和SELECT COUNT(*) - 若源库是 MySQL,确保连接用的是
MySQL Native Driver(非 ODBC 或 PDO 模拟),否则自动降级为全缓存模式
目标库写入慢,INSERT 变成逐条提交
Navicat 数据传输默认按每 100 行打包一次 INSERT,但实际发给 MySQL 的仍是多条独立语句,没利用 MySQL 的批量插入协议。更糟的是,它不关索引、不设 autocommit=0,每行都触发日志刷盘和索引更新。
- 提前在目标库执行:
SET FOREIGN_KEY_CHECKS = 0;和SET UNIQUE_CHECKS = 0; - 传输前手动删掉目标表所有非主键索引(
DROP INDEX idx_name ON table_name),传完再重建 - 在数据传输向导最后一步,勾选「忽略错误继续」并把「每批记录数」调到
50000(默认是 100)
为什么改了设置还是卡在“正在写入目标表”
大概率是目标 MySQL 服务端没调优,Navicat 把压力全甩过去了。尤其当 innodb_buffer_pool_size 过小或 innodb_log_file_size 太小时,大批量写入会频繁刷盘、阻塞 checkpoint,表现就是写入吞吐骤降、延迟飙升。
- 检查目标库:执行
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';,64GB 内存机器建议设为32G - 确认
innodb_log_file_size≥1G(小于 512M 会严重拖慢大批量写入) - 导入阶段临时设
innodb_flush_log_at_trx_commit = 2(崩溃最多丢 1 秒数据,但写入提速 2–3 倍) - 如果目标库启用了
log_bin(MySQL 8 默认开),加skip-log-bin到配置重启——二进制日志同步是最大隐性瓶颈
真正稳又快的替代方案:绕过 Navicat 封装
Navicat 的「数据传输」本质是 GUI 层封装了 mysqldump + mysql,但去掉了关键参数控制权。超过 500MB 的表,直接用命令行:
mysqldump --single-transaction --no-create-info --skip-triggers \ -h source_host -u user -p database table_name | \ mysql -h target_host -u user -p database
- 加
--skip-triggers避免触发器拖慢(多数迁移不需要) - 用管道直传,不落地文件,省 SSD 空间和两次 I/O
- 若网络不稳定,加
--compress减少传输量
最易被忽略的一点:Navicat 数据传输不支持并行导出单表,而 mydumper 可以按表多线程——超 10GB 的库,别硬扛。


















