SparkSQL执行计划树符号含义解析:Q0-Q4技术咨询
Hey,这些Spark执行计划里的符号疑问其实都是树形结构展示的小细节,我给你逐个拆解清楚:
测试代码
test("SparkSQLTest 0005") { val spark = SparkSession.builder().master("local").appName("SparkSQLTest 0005").getOrCreate() spark.range(100, 100000).createOrReplaceTempView("t1") spark.range(2000, 10000).createOrReplaceTempView("t2") val df = spark.sql("select count(1) from t1 join t2 on t1.id = t2.id") df.explain(true) }
执行计划输出
== Parsed Logical Plan == 'Project [unresolvedalias('count(1), None)] //Q0, Why the first line has no +- or :- +- 'Join Inner, ('t1.id = 't2.id) //Q1, What does +- mean :- 'UnresolvedRelation `t1` //Q2 What does :- mean +- 'UnresolvedRelation `t2` == Analyzed Logical Plan == count(1): bigint Aggregate [count(1) AS count(1)#9L] +- Join Inner, (id#0L = id#2L) :- SubqueryAlias t1 : +- Range (100, 100000, step=1, splits=Some(1)) //Q3 What does : +- mean? +- SubqueryAlias t2 +- Range (2000, 10000, step=1, splits=Some(1)) == Optimized Logical Plan == Aggregate [count(1) AS count(1)#9L] +- Project +- Join Inner, (id#0L = id#2L) :- Range (100, 100000, step=1, splits=Some(1)) //Q4 These two Ranges are both Join's children, why one is :- and the other is +- +- Range (2000, 10000, step=1, splits=Some(1)) //Q4 == Physical Plan == *(2) HashAggregate(keys=[], functions=[count(1)], output=[count(1)#9L]) +- *(2) HashAggregate(keys=[], functions=[partial_count(1)], output=[count#11L]) +- *(2) Project +- *(2) BroadcastHashJoin [id#0L], [id#2L], Inner, BuildRight :- *(2) Range (100, 100000, step=1, splits=1) +- BroadcastExchange HashedRelationBroadcastMode(List(input[0, bigint, false])) +- *(1) Range (2000, 10000, step=1, splits=1)
疑问与解答
Q0:解析后的逻辑计划(Parsed Logical Plan)第一行为何没有+-或:-符号?
这行是整个执行计划的根节点,也就是最顶层的操作(这里是Project)。Spark的执行计划输出里,根节点会直接展示,不需要前缀符号——所有带+-/:-的都是它的子节点或更深层次的节点,相当于树形结构把根放在最顶端,不用额外标记。Q1:执行计划中的+-符号代表什么含义?
+-是标记当前节点的直接子节点的通用符号,你可以把它理解成“当前节点的下一级子节点”。比如在Parsed Plan里,'Project的子节点就是'Join,所以用+-连接。不管是逻辑计划还是物理计划,只要是当前节点的普通子节点,都会用这个符号。Q2:执行计划中的:-符号代表什么含义?
:-是专门用来标记Join操作的左子节点的符号——也就是你SQL里JOIN关键字左边的表/数据集。比如你写的t1 join t2,t1是左表,所以在Join节点下,它的左子节点就用:-标记,用来和右子节点明确区分。Q3:执行计划中的: +-符号代表什么含义?
这是层级缩进的延续标记,用来表示它是上一个:-节点的子节点。你看这里:- SubqueryAlias t1下面的: +- Range,意思是Range是t1这个子查询别名的子节点——相当于在左分支的下一层,用: +-来保持缩进和层级关系,让整个计划的树形结构更清晰易读。Q4:Join的两个子节点Range为何分别使用:-和+-符号?
这还是和Join的左右分支有关::-对应的是Join的左输入源(这里是t1对应的Range),+-对应的是Join的右输入源(t2对应的Range)。Spark用这两个符号明确区分Join操作的左右两边,方便你一眼分辨出哪部分是左表、哪部分是右表,在复杂多表Join场景下,这个标记能帮你快速理清数据流向。
内容的提问来源于stack exchange,提问作者Tom

