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

Polars scan_parquet启用Hive分区后仍全量扫描数据集问题咨询

问题描述

我使用pl.sink_parquet创建了一个按date和part_id分区的Parquet数据集,结构如下:

-dataset
 |
 -date=2009-08-01
  |
  -part_id=0
   |
   -0.parquet
  -part_id=1
   |
   -0.parquet
  -...
  -part_id=N
   |
   -0.parquet
 -date=2009-09-01
  |
  -part_id=0
   |
   -0.parquet
  -part_id=1
   |
   -0.parquet
  -...
  -part_id=N
   |
   -0.parquet
  -...
  date=2023-01-01
  |
  ...

原本以为可以通过pl.scan_parquet("dataset", hive_partitioning=True).filter(pl.col("part_id") == 0)快速加载所有part_id=0的Parquet文件,但实际Polars会扫描整个数据集(约60000个文件),耗时约40秒;而手动传入文件路径列表调用scan_parquet仅需约0.5秒。

请问是否是我对scan_parquet的用法存在误解?

补充说明:数据集通过多次调用sink_parquet创建,每次传入仅含单个date的Polars DataFrame,仍将date列为分区列,未手动创建文件夹结构。使用的是Linux系统上的Polars 1.31.0版本。


问题分析与解决

核心原因

这并非用法误解,而是Polars 1.31.0版本处理多层Hive分区时的分区发现逻辑限制:

  • 启用hive_partitioning=True时,Polars需要先遍历整个目录树解析所有分区键(date、part_id),这个过程会扫描所有60000个文件所在的目录,导致耗时过长。
  • 分批写入的方式(每次仅传单个date的DataFrame)没有让Polars优化分区发现路径,它依然会全量遍历目录来识别所有分区值。

优化方案

1. 用通配符直接定位目标分区

利用文件系统通配符限定扫描范围,让Polars只处理part_id=0的目录,避免全量遍历:

pl.scan_parquet("dataset/date=*/part_id=0/*.parquet", hive_partitioning=True)

这种方式会直接匹配符合条件的文件路径,耗时和手动传入路径列表接近。

2. 升级Polars版本

Polars后续版本(如1.32及以上)对Hive分区扫描逻辑做了优化,支持在过滤阶段提前跳过不符合条件的分区目录。若允许升级,建议更新到最新稳定版后测试原代码性能。

3. 统一写入数据集

后续若有新数据写入,尽量一次性写入包含所有date的DataFrame;若必须分批写入,确保目录结构一致性,帮助Polars更高效识别分区键。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 18:12:36