Spark有BroadCastJoin、ShuffleHashJoin、SortMergeJoin三種join方式。首先講一下hash join的過程。
hash join過程,hash join作為單機(jī)算法。1)確定build table和probe table。build table用join key構(gòu)建hash table,probe table使用join key進(jìn)行探測(cè),探測(cè)成功就可以join在一起。小表作為build table,大表作為probe table。2)構(gòu)建hash table,依次讀取build table的數(shù)據(jù),數(shù)據(jù)緩存咋及內(nèi)存中,如果內(nèi)存放不下,則需要dump到磁盤。3)探測(cè),依次掃描probe table中的數(shù)據(jù),使用相同的hash函數(shù)映射hash table中的記錄,映射成功之后再檢查join條件,如果成功就可以將兩者join在一起。
1、BroadCastHashJoin,將其中一張小表廣播分發(fā)到另一張大表所在的分區(qū)節(jié)點(diǎn)上,分別并發(fā)地與其上的分區(qū)記錄進(jìn)行hash join。broadcast適用于表很小,可以直接廣播的場(chǎng)景。
2、ShuffleHashJoin 一旦小表數(shù)據(jù)量較大,此時(shí)不再適合廣播分發(fā)。這種情況下,可以根據(jù)join key相同必然分區(qū)相同的原理,將兩張表按join key重新組織分區(qū),這樣就可以將join分而治之,劃分為很多小join充分利用集群資源并行化。
3、SortMergeJoin 將兩張大表按照join key進(jìn)行重新分區(qū),對(duì)單個(gè)分區(qū)節(jié)點(diǎn)的兩張表分別進(jìn)行排序,對(duì)排好序的兩張表分區(qū)數(shù)據(jù)進(jìn)行join操作。分別便利兩個(gè)有序序列,遇到相同join就merge輸出,否則取更小一邊。
join代價(jià)排序 broadcast hash join < shuffle ahsh join < sortmerge hash join
三種join的hints實(shí)際寫法
A.broadcast hash join 的寫法 (若左右表都滿足小表閾值,則hint不生效,即默認(rèn)broadcast右表,mapjoin左表)
select /** MAPJOIN(t2)*/ from t1 join t2 on t1.id = t2.id
select /** BROADCASTJOIN (t2)*/ from t1 join t2 on t1.id = t2.id
select /** BROADCAST(t2)*/ from t1 join t2 on? t1.id = t2.id
B. sort merge hash join的寫法
select /** MERGE(t1)*/ from t1 join t2 on t1.id = t2.id
select /** SHUFFLE_MERGE(t1)*/ from t1 join t2 on? t1.id = t2.id
select /**MergeJOIN(t1) */ from t1 join t2 on? t1.id = t2.id
C.shuffle hash join的寫法
SELECT /** shuflle_hash(t1)*/ from t1 join t2 on t1.id = t2.id