Spark SQL中多次引用小表不同别名时Broadcast Hint的使用方式疑问
Spark SQL中多次引用小表不同别名时Broadcast Hint的使用方式疑问
你好呀,针对你提出的这个Spark SQL里Broadcast Hint的使用疑问,我来给你梳理清楚:
结论先行
你需要在每个引用小表的子查询中都单独添加Broadcast hint,而不是只加一次。
具体原因
你写的两个子查询small_table_aliasA和small_table_aliasB,都是从同一个small_table中过滤出不同的数据集(分别匹配col_C='abc'和col_C='def'),在Spark的执行计划里,这两个子查询是独立的逻辑单元,对应着两个不同的临时数据集。
Broadcast hint的作用是告诉Spark:「把这个小数据集广播到所有Executor节点」,由于这两个过滤后的数据集是分开的,所以必须为每个子查询单独标记Broadcast hint,这样Spark才会分别将这两个小数据集广播出去,从而避免大表tableBig发生shuffle,保证join的性能。
正确写法示例
就是你自己列出的这种每个子查询都加hint的写法,这里也可以把hint简化为不带表名的/*+ BROADCAST */(因为子查询里只有small_table这一个表),效果是一样的:
select big_table.col_A, dense_rank() over ( order by big_table.col_B, big_table.col_C, nvl(small_table_aliasA.col_a,0), nvl(small_table_aliasB.col_b,0) ) den_key_id, big_table.col_B, big_table.col_C, small_table_aliasA.col_b as aliasA_key, small_table_aliasB.col_b as aliasB_key from tableBig big_table LEFT JOIN (select /*+ BROADCAST */ * from small_table where col_C = 'abc' ) small_table_aliasA ON big_table.col_d = small_table_aliasA.col_d LEFT JOIN (select /*+ BROADCAST */ * from small_table where col_C = 'def' ) small_table_aliasB ON big_table.col_e = small_table_aliasB.col_d
额外小建议
如果你的small_table本身整体数据量很小,也可以通过配置Spark参数spark.sql.autoBroadcastJoinThreshold(默认是10MB),让Spark自动识别小表并进行广播,这样就不用手动添加hint了。但如果需要精确控制哪些数据集被广播,手动加hint的方式会更稳妥。
备注:内容来源于stack exchange,提问作者user1670805
相关产品推荐
相关产品推荐

