【问题标题】:spark sql where clause after select选择后的spark sql where子句
【发布时间】:2020-01-29 03:25:22
【问题描述】:

考虑以下 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 保留了血统。运行letters.explain(true)
  • 谢谢@Andrew 我明白了,但是,我不知道它告诉了我多少。我会发布它。
  • 不太容易理解,我承认。

标签: scala apache-spark apache-spark-sql


【解决方案1】:

继承于 Spark 方法,在一个动作/作业中,在一个阶段中融合代码 --> 缩小转换。

Spark 将优化代码。很多这样的例子。

val rdd1 = ...
val rdd2 = rdd1.map(...
val rdd3 = rdd2.map(...

在这个简单的示例中,由于代码的优化和融合,当 Action 发生时,甚至可能不会出现 rdd2、rdd1。

在您的情况下,您可以将它们融合在一起,然后进行简单的本地表扫描。

您可以查看https://spoddutur.github.io/spark-notes/second_generation_tungsten_engine.html 以了解融合代码(也称为全阶段代码生成)。

【讨论】:

  • 感谢@thebluephantom。我会读一遍然后回来。顺便说一句,我喜欢你的个人资料评论引用“Spark 程序员在 Databricks 风格中使用 Scala,而不是 Monad 学术方法。” :D
  • 我是一名热爱编程的架构师...Spark 很聪明,还有很长的路要走,但是非常有趣的产品
  • 在阅读了更多内容后,我认为您是对的 WSCG 是该行为发生的原因。感谢您的回答,已接受。
猜你喜欢
  • 1970-01-01
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-16
相关资源
最近更新 更多