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

Node.js如何将MySQL千万级大数据集分块有序写入CSV文件

Node.js 分批次导出MySQL大表到CSV避免内容错乱的解决方案

问题核心原因

你当前的storeFile是异步执行逻辑,没有等待当前批次数据完全写入磁盘,就触发了下一批次的查询和写入操作,多个并行的写入流同时向同一个文件追加内容,就会出现行内容混杂、记录无序的问题。

代码改造方案

第一步:改造storeFile为返回Promise的异步方法

将写入完成/失败的回调逻辑封装为Promise,方便上层用await控制执行时序:

const storeFile = (filename, headers, jsonData, append) => {
  return new Promise((resolve, reject) => {
    const flags = append === true ? 'a' : 'w'
    const ws = fs.createWriteStream(filename, { flags })
    fastcsv
      .write(jsonData, { headers, rowDelimiter: '\r\n' })
      .on('error', (err) => {
        logger.error(`csv格式化失败: ${err.message}`)
        ws.destroy()
        reject(err)
      })
      .pipe(ws)
    // 监听写入流完成事件
    ws.on('finish', () => {
      logger.info(`批次写入完成,文件: ${filename}`)
      resolve()
    })
    // 监听写入流错误事件
    ws.on('error', (err) => {
      logger.error(`文件写入失败: ${err.message}`)
      reject(err)
    })
  })
}

第二步:主循环增加await等待写入完成

每次查询到批次数据后,等待当前批次完全写入完成,再更新offset、执行下一轮查询:

// 导出逻辑需要放在async函数内
const exportLargeTableToCsv = async () => {
  const filename = 'test.csv'
  let offset = 0
  let append = false
  let writeHeaders = true
  const limit = 20000
  // 建议动态查询表总条数,不要硬编码
  const totalCount = await Record.count()
  const totalIterations = Math.ceil(totalCount / limit)

  for (let i = 0; i < totalIterations; i++) {
    const records = await Record.findAll({
      offset,
      limit,
      raw: true
    })
    // 等待当前批次写入完成再继续后续逻辑
    await storeFile(filename, writeHeaders, records, append)
    // 首次写入后关闭表头写入、开启追加模式
    writeHeaders = false
    append = true
    offset += limit
    // 可选:打印导出进度
    logger.info(`导出进度: ${((i + 1) / totalIterations * 100).toFixed(2)}%`)
  }
  logger.info('全量数据导出完成')
}

// 执行导出,捕获全局异常
exportLargeTableToCsv().catch(err => {
  logger.error(`导出任务失败: ${err.stack}`)
})

可选优化建议

  • 可全程复用同一个文件写入流和fastcsv实例,避免每次批次都打开/关闭文件的开销,性能更好。
  • 1000万条数据使用offset分页查询,越到后段查询性能越差,建议改用主键排序分页:每次查询时记录当前批次最大的主键ID,下一次查询用where id > 上次最大ID limit 20000的条件查询,性能远高于offset分页。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:27:03