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
相关产品推荐
相关产品推荐

