我正在尝试有效地连接两个DataFrame,其中一个是大的,第二个是小一点。
有没有办法避免这一切洗牌?我无法设置autoBroadCastJoinThreshold
,因为它只支持整数 - 我尝试广播的表略大于整数个字节。
有没有办法强制广播忽略这个变量?
答案 0 :(得分:62)
在SparkSQL中,您可以通过调用queryExecution.executedPlan
来查看正在执行的连接类型。与核心Spark一样,如果其中一个表比另一个表小得多,则可能需要广播散列连接。您可以通过在加入broadcast
之前调用DataFrame
上的方法largedataframe.join(broadcast(smalldataframe), "key")
来向Spark SQL提示应该广播给定DF以进行加入
示例:强>
broadcast
<\ n>以DWH术语表示,大数据框可能类似于 事实
smalldataframe可能类似于 维度
注意:import org.apache.spark.sql.functions.broadcast
以上来自SparkContext
而不是来自spark.sql.conf.autoBroadcastJoinThreshold
Spark也会自动使用def
explain(): Unit
Prints the physical plan to the console for debugging purposes.
来确定是否应该广播一个表。
sqlContext.sql("SET spark.sql.autoBroadcastJoinThreshold = -1")
有没有办法强制广播忽略这个变量?
MAPJOIN
注意:
另一个类似开箱即用的说明w.r.t.蜂巢(不是火花):类似 可以使用下面的hive提示
Select /*+ MAPJOIN(b) */ a.key, a.value from a join b on a.key = b.key hive> set hive.auto.convert.join=true; hive> set hive.auto.convert.join.noconditionaltask.size=20971520 hive> set hive.auto.convert.join.noconditionaltask=true; hive> set hive.auto.convert.join.use.nonstaged=true; hive> set hive.mapjoin.smalltable.filesize = 30000000; // default 25 mb made it as 30mb
来实现...
{{1}}
进一步阅读:请参阅我的article on BHJ, SHJ, SMJ
答案 1 :(得分:17)
您可以使用left.join(broadcast(right), ...)
答案 2 :(得分:4)
设置spark.sql.autoBroadcastJoinThreshold = -1
将完全禁用广播。看到
Other Configuration Options in Spark SQL, DataFrames and Datasets Guide
答案 3 :(得分:3)
答案 4 :(得分:0)
使用连接提示将优先于配置 autoBroadCastJoinThreshold
,因此使用提示将始终忽略该阈值。
此外,当使用连接提示时,format link(自 Spark 3.x 起)也不会改变提示中给出的策略。
在 Spark SQL 中,您可以应用连接提示,如下所示:
SELECT /*+ BROADCAST */ a.id, a.value FROM a JOIN b ON a.id = b.id
SELECT /*+ BROADCASTJOIN */ a.id, a.value FROM a JOIN b ON a.id = b.id
SELECT /*+ MAPJOIN */ a.id, a.value FROM a JOIN b ON a.id = b.id
注意,关键字 BROADCAST、BROADCASTJOIN 和 MAPJOIN 都是 Adaptive Query Execution 中代码中写的别名。