1.小表對大表(broadcast join)
將小表的數據分發到每個節點上,供大表使用。executor存儲小表的全部數據,一定程度上犧牲了空間,換取shuffle操作大量的耗時,這在SparkSQL中稱作Broadcast Join
Broadcast Join的條件有以下幾個:
*被廣播的表需要小於 spark.sql.autoBroadcastJoinThreshold 所配置的值,默認是10M (或者加了broadcast join的hint)
*基表不能被廣播,比如 left outer join 時,只能廣播右表
2.Shuffle Hash Join
因為被廣播的表首先被collect到driver段,然后被冗余分發到每個executor上,所以當表比較大時,采用broadcast join會對driver端和executor端造成較大的壓力。
spark可以通過分區的形式將大批量的數據划分成n份較小的數據集進行並行計算.
利用key相同必然分區相同的這個原理,SparkSQL將較大表的join分而治之,先將表划分成n個分區,再對兩個表中相對應分區的數據分別進行Hash Join,
這樣即在一定程度上減少了driver廣播一側表的壓力,也減少了executor端取整張被廣播表的內存消耗。
*Shuffle Hash Join分為兩步:
對兩張表分別按照join keys進行重分區,即shuffle,目的是為了讓有相同join keys值的記錄分到對應的分區中
對對應分區中的數據進行join,此處先將小表分區構造為一張hash表,然后根據大表分區中記錄的join keys值拿出來進行匹配
*Shuffle Hash Join的條件有以下幾個:
分區的平均大小不超過spark.sql.autoBroadcastJoinThreshold所配置的值,默認是10M
基表不能被廣播,比如left outer join時,只能廣播右表
一側的表要明顯小於另外一側,小的一側將被廣播(明顯小於的定義為3倍小,此處為經驗值)
3.大表對大表(Sort Merge Join)
將兩張表按照join keys進行了重新shuffle,保證join keys值相同的記錄會被分在相應的分區。分區后對每個分區內的數據進行排序,排序后再對相應的分區內的記錄進行連接
因為兩個序列都是有序的,從頭遍歷,碰到key相同的就輸出;如果不同,左邊小就繼續取左邊,反之取右邊(即用即取即丟)