我继续做了一些小实验来回答你的第一个问题。
问题 1:
- 创建了一个包含 3 行 [key,df_a_column] 的数据框
a
- 创建了一个包含 10 行 [key,value] 的数据框
b
- 跑:
spark.sql("SELECT * FROM a JOIN b ON a.key = b.key").explain()
== Physical Plan ==
*(1) BroadcastHashJoin [key#122], [key#111], Inner, BuildLeft, false
:- BroadcastExchange HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [id=#168]
: +- LocalTableScan [key#122, df_a_column#123]
+- *(1) LocalTableScan [key#111, value#112]
正如预期的那样,广播了具有 3 行的 Smaller df a。
- 冉:
spark.sql("SELECT * FROM a JOIN b ON a.key = b.key where b.value=\"bat\"").explain()
== Physical Plan ==
*(1) BroadcastHashJoin [key#122], [key#111], Inner, BuildRight, false
:- *(1) LocalTableScan [key#122, df_a_column#123]
+- BroadcastExchange HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [id=#152]
+- LocalTableScan [key#111, value#112]
在这里您可以注意到数据帧b 已广播!意思是 spark 评估 size AFTER applying where 以选择要广播的那个。
问题 2:
是的,你是对的。从前面的输出中可以明显看出它首先应用的地方。
问题 3:
不,您无法分析,但您可以通过在 SQL 中提示有关它的 spark 来广播 tempView 表。 ref
例如:spark.sql("SELECT /*+ BROADCAST(b) */ * FROM a JOIN b ON a.key = b.key")
如果你现在看到解释:
== Physical Plan ==
*(1) BroadcastHashJoin [key#122], [key#111], Inner, BuildRight, false
:- *(1) LocalTableScan [key#122, df_a_column#123]
+- BroadcastExchange HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [id=#184]
+- LocalTableScan [key#111, value#112]
现在,如果您看到,即使数据帧 b 有 10 行,它也会被广播。
问题1,没有提示,a被广播了。
注意:SQL spark 中的广播提示适用于 2.2
了解物理计划的提示:
- 从
LocalTableScan[ list of columns ] 中找出数据框
- 正在广播
BroadcastExchange 的子树/列表下的数据帧。