SQL 数据导入导出技巧与优化

1次阅读

mysql导入大文件需调高max_allowed_packet至512m并同步配置客户端和服务端;postgresql导出须用pg_dump -fc -o -x,导入用pg_restore –no-owner/–no-privileges;sqlite导出csv应设.charset utf-8并用python csv模块处理转义;时间条件需补全精度,大表导出避免into outfile而用分页拉取。

SQL 数据导入导出技巧与优化

MySQL 导入大文件卡住或报错 max_allowed_packet

导入 SQL 文件时突然中断,错误里带 Got a packet bigger than 'max_allowed_packet' bytes,基本就是这个参数太小了。它限制单次传输的数据包上限,默认才 4MB,而导出的 mysqldump 文件常含超长 INSERT 语句。

实操建议:

  • 导入前临时调高:启动 mysql 客户端时加参数 --max_allowed_packet=512M
  • 服务端也要同步改:在 my.cnf[mysqld][client] 段都加上 max_allowed_packet = 512M,否则 source 命令仍可能失败
  • 别只改客户端——很多同学只改了 mysql 命令行参数,忘了 mysqld 进程本身也有该限制,导致执行到一半被断连

PostgreSQL 用 pg_dumppg_restore 导出导入时权限丢失

导出再导入后,表所有者变成当前登录用户,GRANT 权限全没了,应用连不上表。这不是 bug,是 pg_dump 默认不导出权限和所有权信息。

实操建议:

  • 导出必须加 -O(保留对象所有权)和 -x(不导出权限指令),但更稳妥的是用自定义格式:pg_dump -Fc -O -x -f backup.dump mydb
  • 导入时用 pg_restore --no-owner --no-privileges 可跳过权限还原;若需还原,则确保目标库存在对应角色,且执行用户有 CREATEROLE 权限
  • -Fc 格式比纯文本快、支持并行、能选表恢复,但无法用文本编辑器查看——别误以为“看不见就不是备份”

SQLite 导出 CSV 时中文乱码或字段含逗号崩溃

.mode csv + .output 导出,结果 excel 打开全是乱码,或者某条记录里字段含逗号、换行,CSV 直接错位。SQLite 自带导出不处理编码和转义。

实操建议:

  • 先设编码:.charset UTF-8(注意不是 UTF8,少横线会无效)
  • .headers on 开头,避免字段名被当数据;导出前加 .separator "," 显式声明分隔符
  • 真正安全的方案是绕过 CLI:用 Python 的 sqlite3 模块 + csv.writer,它自动处理引号包裹和特殊字符转义

导出数据时 WHERE 条件写错导致漏数据或锁表

导出前加 WHERE created_at > '2023-01-01',结果发现少了最后一天的数据——因为时间字段是 dateTIME,而字符串比较没包含时分秒;更糟的是,在生产库直接 select ... INTO OUTFILE,表被锁死几分钟。

实操建议:

  • 时间条件务必补全精度:created_at >= '2023-01-01 00:00:00',或用 DATE(created_at) >= '2023-01-01'(但会失索引,慎用)
  • MySQL 的 INTO OUTFILE 要求文件路径在服务端,且只能由拥有 FILE 权限的用户执行——普通应用账号基本没这权限,别硬试
  • 大表导出优先用应用层分页拉取(如 id BETWEEN ? AND ?),避开长事务和锁表风险;导出脚本里记得加 LIMITOFFSET 防崩

导出导入看着只是读写文件,但每一步都卡在细节上:参数没对齐、格式没选对、权限没配好、时间没掐准。最容易忽略的是「两端环境是否一致」——比如导出用 PostgreSQL 14,导入到 12,某些 json 函数就直接报错。

text=ZqhQzanResources