Spark优化规则是否有特定执行顺序?排序原则及案例分析
Spark优化规则的排序要求及核心原则
一、优化规则的排序要求与原则
Spark的Catalyst优化器里的规则不是无序执行的,确实有明确的排序要求,排序主要遵循两个核心逻辑:
- 逻辑依赖优先:如果规则A必须基于规则B的处理结果才能生效,那B就得排在A前面。比如某些规则需要先确定可用列范围,才能进行后续的谓词下推;或者有些规则生成的算子结构,得靠其他规则来进一步优化。
- 性能收益优先:优先执行能带来最大性能提升的规则,尤其是能直接减少数据源读取量的操作——比如提前过滤数据、裁剪列这类优化,越早执行,后续处理的数据量就越小,整体性能提升越明显。
二、两种执行计划的合理性分析
先看两个执行计划的具体结构:
Case 1(Project靠近数据源)
Filter (key#0 < 10) +- Filter (rand(0) > 0.5) +- Project [key#0] +- LocalRelation <empty>, [key#0, value#0]
Case 2(Filter靠近数据源)
Project [key#0] +- Filter (key#0 < 10) +- Filter (rand(0) > 0.5) +- LocalRelation <empty>, [key#0, value#0]
Spark单元测试里把Case 2作为预期结果,原因很直接:
- 谓词下推的收益比列裁剪更高:
rand(0) > 0.5和key#0 < 10这两个过滤逻辑如果靠近数据源,能在读取数据阶段就把不符合条件的数据直接筛掉,后续Project算子要处理的数据量会大幅减少。要是先做Project裁剪列,虽然少了一列数据,但过滤操作还是得处理原数据源的所有行,性能提升远不如提前过滤行数来得实在。 - 逻辑上更合理:Filter需要用到
key#0列,而数据源本身就包含该列,完全不需要先做Project再过滤。先过滤再裁剪列,既能保证Filter拿到需要的字段,又能在过滤后只保留必要的列,避免多余的数据在算子间传输。
这里要说明的是,ColumnPruning和PushDownPredicate的执行顺序不是绝对固定的,但在这个场景下,优先执行谓词下推更符合性能最优的原则——毕竟减少数据行数对后续所有算子的压力缓解,比减少列数的影响更大,尤其是数据量较大的时候。
内容的提问来源于stack exchange,提问作者user23358051
相关产品推荐
相关产品推荐

