使用DuckDB将多份CSV转Parquet时遭遇内存不足问题
解决DuckDB导出Parquet时的内存不足问题
针对你用DuckDB 0.10.0处理12GB CSV转Parquet时的内存溢出问题,结合32GB内存的Windows环境,可尝试以下几种方案:
1. 配置内存与临时目录,让DuckDB磁盘溢出
DuckDB默认优先用内存处理数据,Windows内存管理机制易导致内存耗尽,需强制让溢出数据写入磁盘:
-- 设置临时文件目录(选剩余空间充足的磁盘路径) PRAGMA temp_directory = 'D:/duckdb_temp'; -- 限制DuckDB内存使用,留足够空间给系统(不要占满32GB) PRAGMA memory_limit = '8GB'; -- 关闭插入顺序保障,减少内存开销 PRAGMA preserve_insertion_order = false;
执行以上配置后,重新运行导出命令(无论是直接从CSV导出还是从持久化表导出)。
2. 调整Parquet导出的行组与缓冲区参数
当前设置的行组大小(100000)结合zstd压缩,可能导致单一行组内存占用过高,可调整为更小的行组并设置合理写缓冲区:
COPY (SELECT * FROM read_csv('*.csv', delim = ',', header = false, parallel = true, auto_detect = false, columns = { 'UPRN': 'BIGINT', 'UDPRN': 'INT', 'CHANGE_TYPE': 'VARCHAR(1)', -- 补充剩余70个字段定义 })) TO 'output.parquet' (FORMAT 'parquet', COMPRESSION 'zstd', ROW_GROUP_SIZE 50000, WRITE_BUFFER_SIZE 67108864);
ROW_GROUP_SIZE 50000:减小行组大小,降低单批次内存占用WRITE_BUFFER_SIZE 67108864:设置64MB写缓冲区,避免内存缓存过多未写入数据
3. 降低CSV读取的并行度
并行读取CSV时,多线程同时加载数据可能瞬间占用大量内存,可尝试降低并行线程数或关闭并行:
-- 根据CPU核心数设置线程数(比如4核设为4) PRAGMA threads = 4; -- 读取CSV时关闭并行,改为单线程流式读取 COPY (SELECT * FROM read_csv('*.csv', delim = ',', header = false, parallel = false, auto_detect = false, columns = { 'UPRN': 'BIGINT', 'UDPRN': 'INT', 'CHANGE_TYPE': 'VARCHAR(1)', -- 补充剩余70个字段定义 })) TO 'output.parquet' (FORMAT 'parquet', COMPRESSION 'zstd', ROW_GROUP_SIZE 50000);
4. 检查Windows虚拟内存配置
确保Windows页面文件(虚拟内存)足够大:
- 右键「此电脑」→ 属性 → 高级系统设置 → 性能 → 设置 → 高级 → 虚拟内存 → 更改
- 取消「自动管理所有驱动器的分页文件大小」,为系统盘或数据盘设置自定义大小,推荐最小值设为48GB(32GB物理内存的1.5倍),最大值设为64GB
内容的提问来源于stack exchange,提问作者tjmgis
相关产品推荐
相关产品推荐

