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

MongoDB插入CSV数据耗时长,如何使用多线程优化写入速度

优化CSV导入MongoDB的多线程实现方案

你当前65万行9.5秒的插入性能已经属于正常范围,若要进一步缩短耗时,可以采用「批次分片+多线程并发插入」的方案,既避免全量读取占用过高内存,也能充分利用数据库IO等待的空窗期提升导入效率。

现有代码的问题

  • 第一版全量insert_many方案:一次性读取整个CSV到内存,遇到GB级大文件时会直接占满内存导致程序崩溃
  • 第二版流式单条插入方案:逐行调用insert_one,单条操作的网络IO开销被放大了65万倍,实际插入速度会比你第一版慢至少10倍以上,完全不推荐使用

多线程优化实现

核心逻辑:用标准库concurrent.futures.ThreadPoolExecutor实现多线程,先将CSV按固定批次拆分,每个线程负责插入一个批次的数据,全程流式读取不需要加载全量文件到内存。

import csv
import pymongo
import time
from concurrent.futures import ThreadPoolExecutor

# 可根据自身机器配置调整最优参数
BATCH_SIZE = 10000  # 每批插入的行数
MAX_WORKERS = 4  # 并发线程数,建议设为CPU核心数的1~2倍

def batch_insert(collection, batch):
    """单批次插入函数,供线程调用"""
    collection.insert_many(batch)

def import_csv_to_mongo(csv_path, db_name, collection_name):
    # 初始化Mongo连接,pymongo默认自带连接池,可安全用于多线程
    client = pymongo.MongoClient('localhost', 27017)
    collection = client[db_name][collection_name]
    executor = ThreadPoolExecutor(max_workers=MAX_WORKERS)
    
    # 流式读取CSV,按批次拆分
    batch = []
    futures = []
    with open(csv_path, 'r', encoding='utf-8') as f:
        reader = csv.DictReader(f)
        for row in reader:
            batch.append(row)
            # 攒够一个批次就提交给线程池执行
            if len(batch) >= BATCH_SIZE:
                # 拷贝当前批次,避免后续修改batch影响已提交的任务
                futures.append(executor.submit(batch_insert, collection, batch.copy()))
                batch.clear()
        # 插入最后不足一批的剩余数据
        if batch:
            futures.append(executor.submit(batch_insert, collection, batch))
    
    # 等待所有插入任务执行完成
    for future in futures:
        future.result()
    
    executor.shutdown()
    client.close()
    print(f"所有数据插入完成")

if __name__ == "__main__":
    start = time.time()
    # 替换为你自己的文件路径、库名、集合名
    import_csv_to_mongo("path/to/your/file.csv", "donorschoose", "MapData")
    print(f"总耗时:{time.time() - start} 秒")

额外性能优化建议

  • 导入前先删除目标集合的非必要索引,全部插入完成后再重建索引:插入过程中更新索引会占大量额外开销,删除单条索引可以让插入速度提升30%以上
  • 若对数据一致性要求不高,可以在初始化MongoClient时设置w=0的写策略,不需要等待数据库写入确认,速度可以进一步提升
  • 可以用pandas.read_csv替代标准库的csv模块读取文件,pandas的CSV读取是C语言实现,大文件读取速度比纯Python实现快2~5倍

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 07:36:01