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

Spark 3.4.1中PySpark多列求和执行异常缓慢问题求助

问题原因拆解

1. 多列求和的表达式结构坑

你写的sum([F.col(f"col{i}") for i in range(50)])会生成嵌套的二元加法表达式树——比如50列求和,最终是((((col0+col1)+col2)+...)+col49)这种多层嵌套结构。列数≤20时,树的深度浅,优化器处理起来没压力;但列数≥25时,树的深度超过20层,后续优化器的递归处理开销会指数级上升。

2. Spark 3.4.1与3.1.2的优化器差异

Spark 3.1.2的表达式优化逻辑很简单,对这种嵌套加法树只做基础的类型检查和常量替换,遍历一次就搞定。但Spark 3.4.1升级了优化器,新增了SimplifyBinaryExpressions这类规则,会反复检查加法的关联性、交换性,尝试合并同类操作。但这套逻辑在处理深层嵌套树时,会对每个节点进行多次遍历——比如50列的话,遍历次数会飙升到上千次,直接拖慢执行速度,极端情况会因为重复处理陷入看似“无限执行”的状态。

3. Scala 2.13元组22限制的影响

你怀疑的Scala元组限制确实是诱因:Spark内部处理多列时,列数≤22会用Scala元组封装表达式,优化器能批量处理;但列数>22时,只能用Seq这类集合封装,而3.4.1的优化器对集合封装的表达式没做适配优化,反而触发了更复杂的递归逻辑,进一步放大了性能问题。而3.1.2对超过22列的场景处理逻辑简单,没额外开销,所以正常运行。

额外规避方案

除了你已经做的重构,还有两种更高效的写法:

  • 直接用字符串表达式求和:F.expr(" + ".join([f"col{i}" for i in range(50)])),这种方式生成的是扁平化表达式,优化器处理更快;
  • 转数组后求和:df_data.withColumn("col_sum", F.array_sum(F.array([F.col(f"col{i}") for i in range(50)])))。

内容的提问来源于stack exchange,提问作者ja-bot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:52:38