You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于日期列将大型MySQL表拆分导出至不同文本/CSV文件?

兄弟,我太懂你这种用Python逐行处理百万级数据慢到崩溃的感受了!把所有数据拉到应用层再逐行判断写入,光是数据传输和反复IO的开销就够磨人的。给你几个从数据库层面直接操作的高效方案,比你现在的方法快N倍:

方案1:用MySQL原生SELECT INTO OUTFILE结合存储过程循环导出

这是最直接的数据库原生方案,让MySQL直接把每个日期的数据写入对应文件,完全绕开应用层的开销。

首先创建一个存储过程来处理循环导出:

DELIMITER //
CREATE PROCEDURE export_data_by_date()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE current_date DATE;
  -- 游标获取所有唯一的日期值(如果date_col是字符串类型,要转成DATE类型,比如STR_TO_DATE(date_col, '%d-%m-%Y'))
  DECLARE date_cursor CURSOR FOR SELECT DISTINCT DATE(date_col) FROM your_table_name;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN date_cursor;
  export_loop: LOOP
    FETCH date_cursor INTO current_date;
    IF done THEN
      LEAVE export_loop;
    END IF;
    -- 拼接导出SQL,格式化日期为文件名要求的格式
    SET @export_sql = CONCAT(
      'SELECT col_1, col_2, date_col INTO OUTFILE ''/your/export/directory/',
      DATE_FORMAT(current_date, '%d_%m_%Y'),
      '.csv'' FIELDS TERMINATED BY '' '' OPTIONALLY ENCLOSED BY ''"'' LINES TERMINATED BY ''\n'' FROM your_table_name WHERE DATE(date_col) = ''',
      current_date, ''';'
    );
    PREPARE stmt FROM @export_sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
  END LOOP;
  CLOSE date_cursor;
END //
DELIMITER ;

然后执行存储过程即可:

CALL export_data_by_date();

⚠️ 注意事项:

  • MySQL用户需要拥有FILE权限
  • 指定的导出目录必须是MySQL进程有权限写入的路径(可以用SHOW VARIABLES LIKE 'secure_file_priv';查看允许的导出目录)
  • 如果你的date_col是字符串格式(比如'20-12-2021'),要把DATE(date_col)改成STR_TO_DATE(date_col, '%d-%m-%Y')来正确转换日期
方案2:用Shell脚本配合mysql命令批量导出

如果不想写存储过程,用Shell脚本更灵活,适合运维同学或者喜欢命令行的场景:

#!/bin/bash
# 配置数据库参数
DB_NAME="your_database_name"
TABLE_NAME="your_table_name"
EXPORT_DIR="/path/to/your/export/folder"
DB_USER="your_mysql_user"
DB_PASS="your_mysql_password"

# 创建导出目录(如果不存在)
mkdir -p $EXPORT_DIR

# 获取所有唯一的日期值(同样注意字符串日期的转换)
dates=$(mysql -u$DB_USER -p$DB_PASS $DB_NAME -se "SELECT DISTINCT DATE(date_col) FROM $TABLE_NAME;")

# 循环每个日期导出数据
for date in $dates; do
  # 格式化日期为文件名需要的格式
  formatted_date=$(date -d "$date" +%d_%m_%Y)
  # 执行查询并导出到对应CSV文件
  mysql -u$DB_USER -p$DB_PASS $DB_NAME -se "SELECT col_1, col_2, date_col FROM $TABLE_NAME WHERE DATE(date_col) = '$date';" > "$EXPORT_DIR/$formatted_date.csv"
done

给脚本加执行权限后运行即可:

chmod +x export_script.sh
./export_script.sh
方案3:用mysqldump按日期分片导出

如果数据量超大,mysqldump是更稳定的选择,它专门用于大表备份导出,性能拉满:

#!/bin/bash
DB_NAME="your_database_name"
TABLE_NAME="your_table_name"
EXPORT_DIR="/path/to/your/export/folder"
DB_USER="your_mysql_user"
DB_PASS="your_mysql_password"

mkdir -p $EXPORT_DIR

dates=$(mysql -u$DB_USER -p$DB_PASS $DB_NAME -se "SELECT DISTINCT DATE(date_col) FROM $TABLE_NAME;")

for date in $dates; do
  formatted_date=$(date -d "$date" +%d_%m_%Y)
  # 用mysqldump导出指定日期的数据,--no-create-info表示不导出表结构
  mysqldump -u$DB_USER -p$DB_PASS $DB_NAME $TABLE_NAME --where="DATE(date_col) = '$date'" --no-create-info --tab="$EXPORT_DIR"
  # 重命名导出的文件(默认是TABLE_NAME.txt)
  mv "$EXPORT_DIR/$TABLE_NAME.txt" "$EXPORT_DIR/$formatted_date.csv"
done

如果需要逗号分隔的CSV,可以加上参数:--fields-terminated-by=',' --fields-enclosed-by='"'

为什么这些方案比Python逐行快?

你之前的Python方案需要把所有百万条数据从数据库拉到应用内存,再逐行判断写入文件,中间经历了「数据库→应用层→文件」的多环节传输和处理;而上面的方案都是让数据库直接把结果输出到文件,或者通过命令行直接定向到文件,省去了应用层的内存占用和反复IO开销,百万级数据下速度能提升几个数量级。

内容的提问来源于stack exchange,提问作者Atif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 05:54:09