Spark广播变量之超大表left join小表详细介绍

项目场景:

最近工作中遇到一个场景:
有一个超大表3.5T和一个小表963K
需要做关联查询,使用到广播变量,广播小表数据,left join后接小表。
领提出优化,说小表在左left join可以执行效率,为了验证领导所说的,专门进行了测试


问题描述:

使用一个300m的表和10k的表进行测试,结果如下:
left join,小表在右进行广播
sparkSQL-执行计划如下:

Spark广播变量之超大表left join小表详细介绍
可以看出是BroadcastHashJoin,
使用这个 Join 策略必须满足以下条件:
•小表的数据必须很小,可以通过 spark.sql.autoBroadcastJoinThreshold 参数来配置,默认是 10MB,如果你的内存比较大,可以将这个阈值适当加大;如果将 spark.sql.autoBroadcastJoinThreshold 参数设置为 -1,可以关闭 BHJ;
•只能用于等值 Join,不要求参与 Join 的 keys 可排序;
•除了 full outer joins ,支持所有的 Join 类型。
物理计划如下:
Spark广播变量之超大表left join小表详细介绍

left join,小表在左进行广播
Spark广播变量之超大表left join小表详细介绍
执行计划是没有广播数据,而是进行了SortMergeJoin,也是对两张表参与 Join 的 Keys 使用相同的分区算法和分区数进行分区,目的就是保证相同的 Keys 都落到相同的分区里面,分区完之后再对每个分区按照参与 Join 的 Keys 进行排序,最后 Reduce 端获取两张表相同分区的数据进行 Merge Join
里面使用了 SortMergeJoin,物理计划如下
Spark广播变量之超大表left join小表详细介绍


原因分析:

Broadcast Hash Join 的实现是将小表的数据广播(broadcast)到 Spark 所有的 Executor 端,这个广播过程和我们自己去广播数据没什么区别,先利用 collect 算子将小表的数据从 Executor 端拉到 Driver 端,然后在 Driver 端调用 sparkContext.broadcast 广播到所有 Executor 端;然后在 Executor 端这个广播出去的数据会和大表进行 Join 操作,这种 Join 策略避免了 Shuffle 操作。一般而言,使用left join时会将广播后的表放在右