SELECT ... INTO OUTFILE 最快但受限于 FILE 权限和 secure_file_priv 配置;命令行加 --batch --raw 配合 sed 可绕过权限问题;Python 脚本最稳妥,支持 UTF-8 BOM、自动转义及流式处理大表。

用 SELECT ... INTO OUTFILE 最快但有权限限制
MySQL 原生支持直接导出为 CSV,但前提是 MySQL 服务进程有写入目标路径的权限,且你拥有 FILE 权限。它不经过客户端,是服务端直接写文件,所以快、可控性强。
-
INTO OUTFILE只能写到 MySQL 服务器本地磁盘(不是你的本地电脑),路径必须是绝对路径,例如/tmp/export.csv - 必须显式指定字段分隔符和行结束符,否则默认用制表符
\t和换行\n,不是标准 CSV - 示例语句:
SELECT id, name, created_at FROM users INTO OUTFILE '/tmp/users.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n';
- 如果报错
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option...,说明secure_file_priv被设定了白名单目录,得先查:SHOW VARIABLES LIKE 'secure_file_priv';,只能导出到该路径下
用 mysql 命令行加 --batch 和 --raw 绕过权限问题
如果你没权限用 INTO OUTFILE,或者想导出到自己机器上,命令行工具配合 shell 处理更实际。关键是关闭列名输出、禁用转义、控制分隔符。
- 加
--batch(或-B)让输出用 tab 分隔;再加--raw(或-r)避免反斜杠转义,这对含换行、引号的字段很重要 - 用
sed或awk把 tab 换成逗号,并给每字段加双引号(可选但推荐):mysql -u root -p -D mydb -N -B -r -e "SELECT id, name, email FROM users;" | sed 's/\t/","/g' | sed 's/^/"/;s/$/"/' > users.csv
-
-N省略列头,-B启用 batch 模式,-r关闭转义——三者缺一不可,否则 CSV 容易错位或损坏 - 注意:如果字段本身含逗号或换行符,纯
sed替换无法生成合规 CSV,此时应改用 Python 或csvkit工具处理
用 Python 的 mysql-connector-python + csv 模块最稳妥
当数据含特殊字符、需要编码控制(如 UTF-8 BOM)、或要加表头时,脚本方式最可靠。不用依赖 MySQL 服务端配置,也不用担心 shell 转义陷阱。
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
- 关键点:连接时指定
charset='utf8mb4',写文件时用encoding='utf-8-sig'防 Excel 打开乱码 -
csv.writer自动处理引号、逗号、换行等转义,比手写sed安全得多 - 简例:
import mysql.connector import csv <p>conn = mysql.connector.connect(host='localhost', user='root', password='xxx', database='mydb', charset='utf8mb4') cursor = conn.cursor() cursor.execute("SELECT id, name, email FROM users") with open('users.csv', 'w', newline='', encoding='utf-8-sig') as f: writer = csv.writer(f, quoting=csv.QUOTE_MINIMAL) writer.writerow([desc[0] for desc in cursor.description]) # 写表头 writer.writerows(cursor.fetchall()) cursor.close() conn.close() - 别漏掉
newline=''参数,Windows 下不加会导致空行;quoting=csv.QUOTE_MINIMAL是平衡安全与可读性的默认选择
导出大表时容易卡住或内存爆掉
一次性拉取百万行进内存再写 CSV,Python 脚本会吃光内存,mysql 命令行也可能因缓冲区溢出失败。必须流式处理。
- MySQL 端用
LIMIT+OFFSET分页风险高(深度分页慢),推荐用主键范围分片,例如:WHERE id BETWEEN 10000 AND 19999 - Python 中用
cursor.fetchmany(size=10000)替代fetchall(),边取边写,内存占用恒定 - 命令行方式无内置流控,大表慎用;若坚持用,可结合
mysql --quick(启用 mysql_use_result)减少客户端内存占用 - CSV 文件本身无“大文件标准”,但 Excel 打开超过 1048576 行会截断——导出前心里要有数,必要时拆分成多个文件
导出 CSV 看似简单,真正踩坑的地方都在权限、编码、特殊字符和大数据量这四块。尤其别小看 secure_file_priv 和 utf-8-sig 这两个细节,它们往往决定你花十分钟还是两小时搞定。

















