超大规模DataFrame筛选:关联日历表与between范围过滤性能对比
两种日期过滤方案性能对比判定方法及结论
判定稳定性能差异的方法
- 执行计划校验:分别对两段代码调用
explain("extended")打印完整物理执行计划,重点对比3个核心指标:扫描的原始数据量预估、shuffle总次数、join算子数量。如果两种方案的执行计划在这三个指标上有固定差异,那性能差就是稳定的。 - 同环境基准测试:保持集群资源分配、Spark配置(并行度、广播阈值、缓存策略等)、源数据状态完全一致的前提下,分别运行两个方案3~5次,排除偶然的集群资源波动影响后,取平均耗时、shuffle读写总量、作业各阶段耗时做对比,就能得到稳定的性能差异结果。
- Spark UI指标对比:运行作业时查看Spark UI的Stage页面,重点对比初始数据扫描阶段的扫描行数、耗时,以及所有join阶段的shuffle数据量,这两个指标的差异直接决定了最终耗时差距。
性能结论
第二种between范围过滤的方案几乎始终比三次join方案更快,核心原因如下:
- 减少了一次join开销:第一种方案需要多执行一次和
calendar_df的leftsemi join,哪怕calendar_df很小触发了广播join,也会多一次全量数据匹配的开销;如果没有触发广播,还会多一次shuffle操作,开销会进一步放大。 - 谓词下推效率更高:between范围过滤属于最简单的谓词条件,Spark可以直接将该条件下推到存储层,读取源数据时直接跳过不符合日期范围的行组/分区,不需要把20亿条全量记录都加载到内存处理;而join过滤的逻辑无法下推到存储层,需要先把所有date_int对应的记录都加载后再做匹配,扫描的数据量差距极大。
- 过滤时机更早:范围过滤是在所有join操作之前执行,会先砍掉不符合日期的大量记录,后续两次join需要处理的数据量远小于先做id join再过滤日期的方案,后续join的开销会更低。
注意:你提供的第二份代码存在字段名错误,
orig_df的日期字段为date_int,代码里写的enc_dt_int需要修正,否则会报错。
内容的提问来源于stack exchange,提问作者ironv
相关产品推荐
相关产品推荐

