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

Spark物理计划与Web UI SQL标签中DAG的差异解析

关于Spark物理计划与Web UI SQL标签DAG的差异问题

原本认为Spark物理计划与Web UI SQL标签中展示的DAG,除了后者会填充运行时统计数据外应该完全一致,且Web UI的SQL标签内容仅在触发Action后可见(因需这些运行时统计数据)。但实际并非如此:

可完整运行示例

import pandas as pd
import numpy as np

df1=  pd.DataFrame(np.arange(1_000).reshape(-1,10))
df1.index = np.random.choice(range(10),size=100)
df1.to_csv("./df1.csv",index_label = "index")
############################################################################

from pyspark.sql import SparkSession
from pyspark.sql import functions as F
from pyspark.sql.types import StructType, StringType, StructField

spark = SparkSession.builder.config("spark.sql.autoBroadcastJoinThreshold","-1").\
config("spark.sql.adaptive.enabled","false").getOrCreate()

schema = StructType([StructField('index', StringType(), True),
                     StructField('0', StringType(), True), 
                     StructField('1', StringType(), True), 
                     StructField('2', StringType(), True), 
                     StructField('3', StringType(), True), 
                     StructField('4', StringType(), True), 
                     StructField('5', StringType(), True), 
                     StructField('6', StringType(), True), 
                     StructField('7', StringType(), True), 
                     StructField('8', StringType(), True), 
                     StructField('9', StringType(), True)])

df1 = spark.read.csv("./df1.csv", header=True, schema = schema)

df2 = df1.select("index","0","1")
df3 = df1.select("index","2","3")

df4 = df1.join(df2,on='index').join(df3,on="index")

df4.explain(mode="formatted")
df4.count()

物理计划输出

== Physical Plan ==
* Project (16)
+- * SortMergeJoin Inner (15)
   :- * Project (10)
   :  +- * SortMergeJoin Inner (9)
   :     :- * Sort (4)
   :     :  +- Exchange (3)
   :     :     +- * Filter (2)
   :     :        +- Scan csv  (1)
   :     +- * Sort (8)
   :        +- Exchange (7)
   :           +- * Filter (6)
   :              +- Scan csv  (5)
   +- * Sort (14)
      +- Exchange (13)
         +- * Filter (12)
            +- Scan csv  (11)

上述物理计划显示有3次独立的数据扫描,但Web UI的SQL标签DAG中仅呈现1次CSV数据源扫描节点。

核心问题

Spark物理计划与Web UI SQL标签中展示的DAG具体有何差异?


差异解析

1. 优化阶段的本质差异

  • explain输出的物理计划是逻辑优化后、执行前的推导版本,此时仅完成了逻辑到物理的转换,尚未应用执行阶段的最终任务复用优化。
  • Web UI展示的是实际执行时的最终物理计划,Spark会在提交作业前做最后一步优化:对于同一数据源的重复扫描,若没有冲突的转换逻辑(比如不同的过滤条件),会自动复用扫描任务,避免重复读取磁盘数据,因此你看到Web UI中仅显示1次扫描。

2. 展示粒度与视角差异

  • explain的物理计划是逻辑执行树的细粒度拆解,会完整列出每个逻辑分支对应的物理节点,哪怕后续会被合并。
  • Web UI的DAG是任务执行的粗粒度可视化,聚焦于实际运行的任务单元,合并了复用的任务节点,同时附带运行时统计数据(如处理数据量、耗时)。

3. 触发时机与内容维度差异

  • explain无需触发Action即可生成,它基于逻辑计划推导物理执行路径,不包含任何运行时数据。
  • Web UI的SQL标签内容必须触发Action后才会生成,因为它记录的是作业实际执行的全量信息,包含运行时优化结果、任务执行统计等维度的数据。

结合示例的具体说明

你的代码中df1被多次用于生成df2、df3并参与join操作,explain输出的物理计划会先按逻辑分支生成3次扫描节点;但Spark在实际执行时,判断这三次扫描读取的是同一个CSV文件,且没有冲突的转换逻辑,因此自动复用了一次扫描任务,最终Web UI中仅呈现1次扫描节点。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 23:04:56