SparkSQL的3种Join实现( 三 )


文章插图
 
可以看到,首先将两张表按照join keys进行了重新shuffle,保证join keys值相同的记录会被分在相应的分区 。分区后对每个分区内的数据进行排序,排序后再对相应的分区内的记录进行连接,如下图示:

SparkSQL的3种Join实现

文章插图
 
看着很眼熟吧?也很简单,因为两个序列都是有序的,从头遍历,碰到key相同的就输出;如果不同,左边小就继续取左边,反之取右边 。
可以看出,无论分区有多大,Sort Merge Join都不用把某一侧的数据全部加载到内存中,而是即用即取即丢,从而大大提升了大数据量下sql join的稳定性 。
SparkSQL对两张大表join采用了全新的算法-sort-merge join,如下图所示,整个过程分为三个步骤:
SparkSQL的3种Join实现

文章插图
 
1. shuffle阶段:将两张大表根据join key进行重新分区,两张表数据会分布到整个集群,以便分布式并行处理;
2. sort阶段:对单个分区节点的两表数据,分别进行排序;
3. merge阶段:对排好序的两张分区表数据执行join操作 。join操作很简单,分别遍历两个有序序列,碰到相同join key就merge输出,否则取更小一边,见下图示意:
SparkSQL的3种Join实现

文章插图
 
经过上文的分析,可以明确每种Join算法都有自己的适用场景,数据仓库设计时最好避免大表与大表的join查询,SparkSQL也可以根据内存资源、带宽资源适量将参数
spark.sql.autoBroadcastJoinThreshold调大,让更多join实际执行为broadcast hash join 。
— THE END —

【SparkSQL的3种Join实现】


推荐阅读