Python处理百万级小CSV文件写入SQLite的性能优化求助
首先拍板:Python绝对能搞定这个百万级CSV合并的任务,我之前踩过类似的坑,只要调整实现方式,速度能提上来一大截。下面是几个核心优化方向,按优先级排序,你可以一步步试:
一、先优化IO操作——最慢的环节往往是读文件
- 换掉原生
csv模块,用更快的批量读取库:推荐polars.read_csv或者pandas.read_csv,尤其是Polars,针对大规模数据的解析和内存优化做得非常到位。你可以直接用usecols参数指定要提取的列,不用加载整个CSV,省内存又快。 - 批量处理,别读一个写一个:攒一批比如1000个文件的数据,再一次性写入数据库,能大幅减少数据库连接和磁盘IO的开销。
- 先缓存本地(如果是从URL拉取):反复请求网络的延迟是致命的,先把所有CSV批量下载到本地临时目录再处理。可以用
concurrent.futures.ThreadPoolExecutor做多线程下载,比单线程快好几倍。
二、数据库操作的性能翻倍技巧
- 手动控制事务,关闭自动提交:SQLite默认每写一条就提交一次,这在百万级数据下会慢到离谱。改成手动开启事务:
这一步能把写入速度提升几十倍,亲测有效。conn = sqlite3.connect('your_db.db') conn.execute("BEGIN TRANSACTION") # 批量插入数据 conn.commit() - 用
executemany做参数化批量插入:别用字符串拼接SQL语句,把数据整理成元组列表,一次性传给数据库。比如:parsed_data = [(parsed_date, col_a, col_b) for ...] cursor.executemany("INSERT INTO your_table (date_col, col1, col2) VALUES (?, ?, ?)", parsed_data) - 调整SQLite的配置:
- 开启WAL模式:
conn.execute("PRAGMA journal_mode = WAL"),这个模式下读写可以并行,写入速度会显著提升。 - 降低同步级别:如果能接受极小的断电数据丢失风险,可以设
PRAGMA synchronous = OFF;保守点就用NORMAL,比默认的FULL快很多。
- 开启WAL模式:
- 最后再建索引:别在写入数据的时候创建索引,等所有数据都导入完成后,一次性创建索引,建索引的开销会小很多。
三、并行/异步处理,榨干CPU和网络资源
- 多进程处理解析任务:因为Python的GIL限制,CPU密集型的日期解析、数据清洗用多进程更合适。用
concurrent.futures.ProcessPoolExecutor把文件列表分成多个批次,每个进程处理一批,注意每个进程要单独创建数据库连接,或者用一个专门的进程负责写入,其他进程把处理好的数据发过去。 - 异步拉取网络文件:如果CSV是从URL获取的,用
aiohttp做异步请求,比多线程更高效,能减少等待网络响应的时间。
四、数据预处理的细节优化
- 批量解析日期:别在循环里逐行解析日期,用库的批量解析功能。比如Polars的
str.to_date或者Pandas的pd.to_datetime,批量处理一列日期字符串的速度比自己写循环快N倍。 - 严格控制内存:只保留需要的列,日期字段直接解析成日期类型(比如Python的
datetime.date或者库的原生日期类型),别存字符串,既省内存又方便数据库写入。
五、如果Python优化后还是不够,试试这些工具
- Dask:专门处理超大规模数据的Python库,能把任务拆分成小任务并行处理,就算内存不够也能处理,无缝衔接Pandas的API,学习成本低。
- SQLite命令行工具:如果CSV格式完全统一,可以用
sqlite3命令行的.import功能,原生C实现的速度比Python快很多。比如先建表,再批量导入:
注意要先把日期字段预处理好,或者用SQL的sqlite3 your_db.db "CREATE TABLE your_table (date_col DATE, col1 TEXT, col2 INTEGER);" for csv_file in ./temp_dir/*.csv; do sqlite3 your_db.db ".import --csv $csv_file your_table" donestrftime函数在导入后转换。 - Apache Spark:如果数据量达到几十GB级别,Spark的分布式处理能力更强,但学习成本稍高,适合超大规模的场景。
总的来说,先从IO优化+数据库事务这两个最容易见效的点入手,应该就能看到明显的速度提升。Python完全能hold住百万级文件的处理,不用轻易换工具。
内容的提问来源于stack exchange,提问作者Chiyo018
相关产品推荐
相关产品推荐

