考虑以下spark-sql查询:
Seq(("b", 2), ("d", 4), ("a", 1), ("c", 3))
.toDF("letter", "number")
.select($"letter")
.where($"number" > 1)
.show
甚至可以拆分原始查询,并且行为仍然存在:
val letters =
Seq(("b", 2), ("d", 4), ("a", 1), ("c", 3))
.toDF("letter", "number")
.select($"letter")
letters
.where($"number" > 1)
.show
这似乎与延迟加载有关,但是我不确定这里到底发生了什么。
当只保留字母时,为什么可以在where子句中包含$"number"
?
编辑1这里是解释:
letters.explain(true)
== Parsed Logical Plan ==
'Project [unresolvedalias('letter, None)]
+- Project [_1#76942 AS letter#76955, _2#76943 AS number#76956]
+- LocalRelation [_1#76942, _2#76943]
== Analyzed Logical Plan ==
letter: string
Project [letter#76955]
+- Project [_1#76942 AS letter#76955, _2#76943 AS number#76956]
+- LocalRelation [_1#76942, _2#76943]
== Optimized Logical Plan ==
LocalRelation [letter#76955]
== Physical Plan ==
LocalTableScan [letter#76955]
Spark方法的固有特性,即在舞台上的Action / Job中融合代码->狭窄的转换。
Spark将优化代码。许多例子。
val rdd1 = ...
val rdd2 = rdd1.map(...
val rdd3 = rdd2.map(...
在此琐碎的示例中,由于进行了代码的优化和融合,当执行操作时,甚至可能甚至没有rdd2,rdd1。
在您的情况下,您可以将它们融合在一起,而只是进行简单的本地表扫描。
您可以看一下https://spoddutur.github.io/spark-notes/second_generation_tungsten_engine.html来给出融合代码(又称整个阶段代码生成)的想法。