用户登录
个人主页 用户中心 我的订单 添加授权 管理授权
退出登录
用户登录 用户注册
欢迎来到 UC建站系统

Navicat右键导出2.3GB数据库跑47分钟断了三次换mydumper四线程6分钟搞定,数据库导出速度差近8倍怎么选

同一个MySQL数据库里18张表总数据量2.3GB,用Navicat右键导出SQL跑了47分钟还断了三次,换成mydumper四线程并行导出不到6分钟就全搞定了,导出速度差了近8倍

数据库导出这件事有一个很容易被忽略的规律:导出速度的差距不是线性的,是指数级的。几百兆的小库,用Navicat右键导出和用命令行mysqldump,时间差不多——都是十几秒。但一旦数据库超过1GB,命令行工具和图形化工具的差距立刻拉开:图形化工具需要先把数据加载到内存、再渲染到界面、再写入文件,每一步都是瓶颈;命令行工具直接走数据库底层协议流式写入磁盘,中间没有内存中转。而到了10GB以上的大库,连mysqldump都不够用了,必须上mydumper或SELECT INTO OUTFILE这种并行或文件系统级别的方案。

选错工具不光是慢的问题——大表导出过程中内存溢出、连接超时、锁表导致业务中断、导完发现字符编码全乱了,这些坑每一个都能让你多花半天时间。而且不同数据库类型(MySQL、PostgreSQL、MongoDB、SQLite)的导出工具和命令完全不同,没有一个"万能导出工具"能搞定所有场景。

五条导出路线,技术底层完全不同

导出路线代表工具底层机制适用数据量是否锁表价格
命令行原生工具mysqldump / pg_dump / mongodump数据库引擎内置的导出协议,直接流式写入磁盘,无内存中转100MB - 50GB加--single-transaction不锁(InnoDB)¥0
文件系统级导出SELECT INTO OUTFILE / COPY TO / mongoexport数据库直接写文件到服务器磁盘,不经过客户端网络传输1GB - 500GB读锁(SELECT时)¥0
多线程并行导出mydumper / pg_dump -j / 自写Python多线程脚本多线程同时导出不同表/不同分片,充分利用CPU和磁盘IO5GB - 1TB+取决于引擎和参数¥0
图形化工具导出Navicat / DBeaver / DataGrip / HeidiSQL客户端先接收全部数据到内存,再写入文件,GUI渲染层有额外开销10KB - 500MB取决于工具实现¥0 - ¥4599/年
云平台快照导出阿里云RDS备份恢复 / AWS RDS快照 / 腾讯云数据迁移物理层快照,直接复制数据文件,不走SQL层任意大小不锁表(物理快照)按存储/流量计费

五条路线的本质区别在于数据从数据库磁盘到你的文件,中间经过了什么。命令行原生工具走的是数据库内部协议,数据直接从存储引擎流到你的硬盘。图形化工具多了一层客户端内存中转和GUI渲染。文件系统级导出完全绕过了网络传输——数据从数据库磁盘直接写到服务器本地文件。多线程导出则是在第一条路线的基础上加上了并行能力。云平台快照是物理层复制,根本不走SQL逻辑层。

MySQL:从mysqldump到mydumper,差距不止是速度

mysqldump:最通用的方案,但大库扛不住

mysqldump是MySQL自带的命令行导出工具,所有MySQL环境都能用,不需要额外安装。单表几百万条数据以内表现稳定,但超过千万行后单线程逐表导出的短板就暴露了——一张大表导出可能需要几十分钟,而且导出的SQL文件导入回去也要同等甚至更长时间。

三个必加参数:--single-transaction(InnoDB不锁表,保证一致性读)、--quick(逐行读取而非全部加载到内存)、--default-character-set=utf8mb4(防止中文乱码)。少了任何一个,轻则导出失败,重则锁表导致线上业务中断。

1 - Navicat右键导出2.3GB数据库跑47分钟断了三次换mydumper四线程6分钟搞定,数据库导出速度差近8倍怎么选 - UC建站系统

mydumper:并行导出,大库场景速度翻几倍

mydumper是mysqldump的多线程替代品,C++编写,底层机制完全不同:它不是逐表导出,而是把每张表按主键分成多个数据块(chunk),然后多个线程同时导出不同的块。一张2GB的大表,mydumper开4个线程,每个线程导出500MB的数据块,理论上时间是mysqldump的四分之一。

关键参数:-t 4(4个线程)、-r 1000000(每100万行一个文件)、--rows-per-chunk 100000(每个chunk包含10万行)。线程数不是越多越好,建议设为CPU核心数的一半到等于核心数之间。

SELECT INTO OUTFILE:最快但最受限

这条SQL语句让MySQL直接把查询结果写成文件放在服务器磁盘上,不经过客户端网络传输,速度是所有方案里最快的。但它有三个硬伤:需要FILE权限(很多云数据库禁用了)、文件生成在服务器端(你还需要再下载)、格式是纯CSV(不含表结构)。适合做数据分析导出,不适合做备份迁移。

2 - Navicat右键导出2.3GB数据库跑47分钟断了三次换mydumper四线程6分钟搞定,数据库导出速度差近8倍怎么选 - UC建站系统

MySQL批量导出Shell脚本(三种模式一键切换)

#!/bin/bash# MySQL批量导出脚本 - 支持mysqldump/mydumper/SELECT INTO OUTFILE三种模式DB_USER="root"DB_PASS="your_password"DB_HOST="localhost"OUTPUT_DIR="./db_export_$(date +%Y%m%d_%H%M%S)"MODE="${1:-mysqldump}"  # 默认mysqldump,可选 mydumper / outfileTHREADS=4mkdir -p "$OUTPUT_DIR"# ============ 模式1:mysqldump批量导出(全库所有表) ============dump_all_tables_mysqldump() {echo "=== 模式:mysqldump 全库导出 ==="# 获取所有数据库列表(排除系统库)databases=$(mysql -u"$DB_USER" -p"$DB_PASS" -h"$DB_HOST" -N -e \"SELECT SCHEMA_NAME FROM information_schema.SCHEMATAWHERE SCHEMA_NAME NOT IN ('information_schema','mysql','performance_schema','sys')")for db in $databases; doecho "  导出数据库: $db"mysqldump -u"$DB_USER" -p"$DB_PASS" -h"$DB_HOST" \--single-transaction \--quick \--default-character-set=utf8mb4 \--routines --triggers --events \"$db" > "$OUTPUT_DIR/${db}.sql"if [ $? -eq 0 ]; thensize=$(du -h "$OUTPUT_DIR/${db}.sql" | cut -f1)echo "    ✓ ${db}.sql ($size)"elseecho "    ✗ ${db} 导出失败"fidone}# ============ 模式2:mydumper并行导出(大库推荐) ============dump_all_tables_mydumper() {echo "=== 模式:mydumper 并行导出(${THREADS}线程) ==="databases=$(mysql -u"$DB_USER" -p"$DB_PASS" -h"$DB_HOST" -N -e \"SELECT SCHEMA_NAME FROM information_schema.SCHEMATAWHERE SCHEMA_NAME NOT IN ('information_schema','mysql','performance_schema','sys')")for db in $databases; doecho "  导出数据库: $db"mydumper \-u "$DB_USER" -p "$DB_PASS" -h "$DB_HOST" \-B "$db" \-t "$THREADS" \-r 1000000 \--rows-per-chunk 100000 \-o "$OUTPUT_DIR/${db}_mydumper" \--compressif [ $? -eq 0 ]; thenecho "    ✓ ${db} 导出完成(mydumper格式)"elseecho "    ✗ ${db} 导出失败"fidone}# ============ 模式3:SELECT INTO OUTFILE(数据分析用) ============dump_all_tables_outfile() {echo "=== 模式:SELECT INTO OUTFILE(CSV格式,最快) ==="databases=$(mysql -u"$DB_USER" -p"$DB_PASS" -h"$DB_HOST" -N -e \"SELECT SCHEMA_NAME FROM information_schema.SCHEMATAWHERE SCHEMA_NAME NOT IN ('information_schema','mysql','performance_schema','sys')")for db in $databases; dotables=$(mysql -u"$DB_USER" -p"$DB_PASS" -h"$DB_HOST" -N -e \"SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='$db'")for table in $tables; dooutfile="/var/lib/mysql-files/${db}_${table}.csv"mysql -u"$DB_USER" -p"$DB_PASS" -h"$DB_HOST" "$db" -e \"SELECT * INTO OUTFILE '$outfile'FIELDS TERMINATED BY ','OPTIONALLY ENCLOSED BY '\"'LINES TERMINATED BY '\n'FROM \`$table\`;"if [ $? -eq 0 ]; thenecho "    ✓ ${db}.${table} → $outfile"fidonedone}# 执行case "$MODE" inmysqldump) dump_all_tables_mysqldump ;;mydumper)  dump_all_tables_mydumper ;;outfile)   dump_all_tables_outfile ;;*)         echo "用法: $0 {mysqldump|mydumper|outfile}" ;;esacecho ""echo "导出完成,文件保存在: $OUTPUT_DIR"

PostgreSQL:pg_dump的三张牌和COPY命令的王炸

PostgreSQL的导出生态比MySQL更丰富。pg_dump有四种导出格式,每种对应不同的使用场景:

导出格式pg_dump参数文件类型恢复方式优势适用场景
plain(纯文本SQL)默认格式.sql 文本文件psql直接执行可读可编辑,跨版本兼容最好小库迁移、需要手动修改SQL
custom(自定义压缩)-Fc.dump 二进制文件pg_restore恢复压缩率高,支持选择性恢复(只恢复某张表)日常备份、生产环境首选
directory(目录格式)-Fd目录(每表一个文件)pg_restore恢复支持并行导出(-j参数),大库首选大库导出,需要并行加速
tar(归档格式)-Ft.tar 归档文件pg_restore恢复兼容传统备份工具链需要与tar工具链配合的场景

如果只是为了把数据导出来做分析,COPY命令比pg_dump快得多。COPY是PostgreSQL的批量数据导出命令,直接把表数据写成CSV或文本文件,不走SQL解析层,速度比SELECT查询再写入文件快3-5倍。

PostgreSQL批量导出Python脚本

import subprocessimport osimport globfrom datetime import datetimeclass PostgreSQLExporter:"""PostgreSQL批量导出工具,支持pg_dump全库/按表/COPY三种模式"""def __init__(self, host="localhost", port=5432, user="postgres",password=None, dbname=None):self.host = hostself.port = portself.user = userself.password = passwordself.dbname = dbnameself.env = os.environ.copy()if password:self.env["PGPASSWORD"] = passworddef export_database(self, dbname: str, output_dir: str,format: str = "custom", jobs: int = 4) -> bool:"""导出整个数据库format: plain/custom/directory/tarjobs: 并行任务数(仅directory格式有效)"""os.makedirs(output_dir, exist_ok=True)timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")ext_map = {"plain": "sql", "custom": "dump", "directory": "", "tar": "tar"}fmt_flag = {"plain": "-Fp", "custom": "-Fc", "directory": "-Fd", "tar": "-Ft"}out_path = os.path.join(output_dir, f"{dbname}_{timestamp}.{ext_map[format]}")cmd = ["pg_dump", "-h", self.host, "-p", str(self.port),"-U", self.user, "-d", dbname,fmt_flag[format], "-f", out_path,"--no-owner", "--no-acl"]if format == "directory" and jobs > 1:cmd.extend(["-j", str(jobs)])result = subprocess.run(cmd, env=self.env, capture_output=True, text=True)if result.returncode == 0:size = os.path.getsize(out_path) if format != "directory" else \sum(os.path.getsize(f) for f in glob.glob(f"{out_path}/*"))print(f"  ✓ {dbname}: {size/1024/1024:.1f}MB → {out_path}")return Trueelse:print(f"  ✗ {dbname}: {result.stderr.strip()}")return Falsedef export_table_csv(self, dbname: str, schema: str, table: str,output_dir: str) -> bool:"""使用COPY命令导出单表为CSV(最快方式)"""import psycopg2os.makedirs(output_dir, exist_ok=True)out_path = os.path.join(output_dir, f"{schema}.{table}.csv")conn = psycopg2.connect(host=self.host, port=self.port, user=self.user,password=self.password, dbname=dbname)cur = conn.cursor()try:with open(out_path, "w", encoding="utf-8") as f:cur.copy_expert(f"COPY {schema}.\"{table}\" TO STDOUT "f"WITH CSV HEADER DELIMITER ',' ENCODING 'UTF8'",f)size = os.path.getsize(out_path)print(f"  ✓ {schema}.{table}: {size/1024/1024:.1f}MB → {out_path}")return Trueexcept Exception as e:print(f"  ✗ {schema}.{table}: {e}")return Falsefinally:cur.close()conn.close()def export_all_tables_csv(self, dbname: str, output_dir: str) -> dict:"""批量导出所有表为CSV"""import psycopg2conn = psycopg2.connect(host=self.host, port=self.port, user=self.user,password=self.password, dbname=dbname)cur = conn.cursor()# 获取所有用户表cur.execute("""SELECT schemaname, tablenameFROM pg_tablesWHERE schemaname NOT IN ('pg_catalog', 'information_schema')ORDER BY schemaname, tablename""")tables = cur.fetchall()cur.close()conn.close()results = {"success": 0, "failed": []}for schema, table in tables:if self.export_table_csv(dbname, schema, table, output_dir):results["success"] += 1else:results["failed"].append(f"{schema}.{table}")return results# 使用示例exporter = PostgreSQLExporter(host="localhost", user="postgres", password="your_password")# 导出整个数据库(custom压缩格式,生产环境推荐)exporter.export_database("my_database", "./pg_export", format="custom")# 导出大库(directory格式 + 4线程并行)exporter.export_database("big_database", "./pg_export_big",format="directory", jobs=4)# 批量导出所有表为CSV(数据分析用)result = exporter.export_all_tables_csv("my_database", "./pg_csv_export")print(f"完成: {result['success']}张表, 失败{len(result['failed'])}张")

MongoDB和SQLite:两个特殊选手

数据库导出工具导出格式核心特点适用场景
MongoDBmongodumpBSON二进制原生备份工具,保留所有数据类型,恢复用mongorestore备份迁移
mongoexportJSON/CSV导出为人类可读格式,可指定查询条件过滤数据数据分析、跨系统对接
mongodump --archive归档流直接输出到stdout,可管道压缩,无需中间文件大库备份(节省磁盘IO)
SQLite.dump命令SQL文本sqlite3命令行内置,一键导出全库SQL备份迁移
Python sqlite3 + csvCSV/ExcelPython标准库直接读取,灵活导出任意格式数据分析、报表

七款图形化工具导出功能横评

工具支持数据库导出格式批量导出大数据量表现价格
Navicat PremiumMySQL/PostgreSQL/SQLite/MongoDB/Oracle/SQL Server等8种SQL/CSV/Excel/JSON/XML/DBF等✅ 多表多选批量导出+定时任务中等,500MB以上明显变慢订阅¥1299/年,永久版约¥4599
DBeaver支持80+种数据库(JDBC驱动)SQL/CSV/Excel/JSON/XML/HTML/Markdown✅ 多表导出+任务调度中等,大表导出建议配合分页免费(社区版),Pro版$12/月
DataGripMySQL/PostgreSQL/Oracle/SQL Server/MongoDB等20+种SQL/CSV/Excel/JSON/HTML/TSV✅ 导出向导支持多表+自定义查询较好,流式导出减少内存占用$99/年(个人版),$199/年(企业版)
HeidiSQLMySQL/MariaDB/PostgreSQL/SQL ServerSQL/CSV/HTML/XML/LaTeX✅ 批量导出表+支持命令行模式较好,轻量级内存占用低免费(开源)
MySQL WorkbenchMySQL/MariaDBSQL/CSV/JSON/XML✅ Data Export支持多库多表中等,大表容易超时免费(MySQL官方)
TablePlusMySQL/PostgreSQL/SQLite/MongoDB/Redis等10+种SQL/CSV/JSON✅ 多选导出较好,原生应用性能不错免费版功能受限,$89永久版
DbGateMySQL/PostgreSQL/SQLite/MongoDB/SQL Server等SQL/CSV/JSON/XML/NDJSON✅ 批量导入导出多表,数据存档功能较好,支持NDJSON流式格式免费(开源)

大表导出的四个保命技巧

技巧一:禁用深分页

WHERE id > last_id递进查询,不要用LIMIT OFFSET。OFFSET 100万意味着MySQL要扫描并跳过前100万行才能拿到结果,越往后越慢。主键递进每次只扫描固定行数。

3 - Navicat右键导出2.3GB数据库跑47分钟断了三次换mydumper四线程6分钟搞定,数据库导出速度差近8倍怎么选 - UC建站系统

技巧二:流式写入不堆积

每读一批数据立即写入文件,不要先把全部数据加载到内存再一次性写。1000万行数据全放内存里就是几个GB,轻则OOM,重则整个服务器卡死。

技巧三:在从库上导出

大表导出会占用大量IO和CPU,在主库上操作直接拖慢线上业务。在只读从库上导出,对业务零影响。如果没有从库,至少选凌晨低峰期执行。

技巧四:导出完必须校验

导出完成后对比源库和导出文件的行数,抽样检查几条数据的内容是否正确。很多人以为"导完了"等于"导对了",结果迁移完发现丢了几万行。

五种场景导出方案速查

场景推荐方案工具预估耗时(10GB数据)费用
日常备份(<500MB小库)图形化工具右键导出DBeaver / HeidiSQL1-3分钟¥0
数据库迁移(1-50GB)命令行原生工具mysqldump / pg_dump -Fc5-20分钟¥0
大库导出(50GB-1TB)多线程并行导出mydumper / pg_dump -Fd -j410-40分钟¥0
数据分析导出(只需部分字段)文件系统级导出SELECT INTO OUTFILE / COPY TO3-10分钟¥0
云数据库迁移云平台快照 + 物理备份下载阿里云RDS备份恢复 / AWS RDS快照取决于云平台带宽按流量计费

数据库导出这件事,核心不是"知不知道mysqldump这个命令",而是能不能根据数据量、导出目的、时间窗口三个变量,在五条技术路线里选对方案。500MB的小库用图形化工具最方便,10GB的中型库用命令行原生工具最稳妥,100GB以上的大库不上并行导出就是在浪费生命。而且别忘了导出完做两件事:检查文件能不能正常恢复,确认导出的数据量和源库一致——这两件事不做,前面花的功夫可能全是白费。

最后说一个容易被忽略的点:导出格式。SQL格式适合备份迁移,CSV适合数据分析,JSON适合程序处理,Excel只适合几百行以内的人工查看。有人用Navicat把一张200万行的表导出为Excel,结果打开文件卡了五分钟,保存还要等半天——不是工具的问题,是格式选错了。

相关推荐
在线客服
👇找客服拿折扣
QQ咨询&售后
在线时间
11:00 ~ 5:30
QQ:3155555535
👇联系QQ
👇联系WX
首页 程序 帮助 登录