left join 和 left semi join区别
左連接與+號, 就是左邊的表數(shù)據(jù)都要。??
select * from a,b where a.id=b.id(+);? ? ??
(+)寫在where后面,不能與or/in連用,ui
?select * from a left join b on a.id=b.id;? ? a里面的數(shù)據(jù)在b里面沒有也要的
?left join 和 left semi join區(qū)別 ? :
left join? A表記錄全部有,如果B表多行的話,A數(shù)據(jù)就被重復(fù)了一次。?
left semi join不重復(fù),找到第一條就返回A行記錄,如果找不到A行記錄不顯示。 就是exists或者 in的意思。
?
1、聯(lián)系
他們都是 hive join 方式的一種,join on 屬于 common join(shuffle join/reduce join),而?left semi join 則屬于 map join(broadcast join)的一種變體,從名字可以看出他們的實現(xiàn)原理有差異。
2、區(qū)別
(1)Semi Join,也叫半連接,是從分布式數(shù)據(jù)庫中借鑒過來的方法。它的產(chǎn)生動機是:對于reduce side join,跨機器的數(shù)據(jù)傳輸量非常大,這成了join操作的一個瓶頸,如果能夠在map端過濾掉不會參加join操作的數(shù)據(jù),則可以大大節(jié)省網(wǎng)絡(luò)IO,提升執(zhí)行效率。
實現(xiàn)方法很簡單:選取一個小表,假設(shè)是File1,將其參與join的key抽取出來,保存到文件File3中,File3文件一般很小,可以放到內(nèi)存中。在map階段,使用DistributedCache將File3復(fù)制到各個TaskTracker上,然后將File2中不在File3中的key對應(yīng)的記錄過濾掉,剩下的reduce階段的工作與reduce side join相同。
由于?hive 中沒有 in/exist 這樣的子句(新版將支持),所以需要將這種類型的子句轉(zhuǎn)成 left semi join。left semi join 是只傳遞表的 join key 給 map 階段 , 如果 key 足夠小還是執(zhí)行 map join, 如果不是則還是 common join。關(guān)于?common join(shuffle join/reduce join)的原理請參考文末 refer。
(2)left semi join?子句中右邊的表只能在?ON 子句中設(shè)置過濾條件,在 WHERE 子句、SELECT 子句或其他地方過濾都不行。
(3)對待右表中重復(fù)key的處理方式差異:因為?left semi join 是 in(keySet) 的關(guān)系,遇到右表重復(fù)記錄,左表會跳過,而 join on 則會一直遍歷。
最后的結(jié)果是這會造成性能,以及 join 結(jié)果上的差異。
(4)left semi join?中最后 select 的結(jié)果只許出現(xiàn)左表,因為右表只有 join key 參與關(guān)聯(lián)計算了,而 join on 默認(rèn)是整個關(guān)系模型都參與計算了。
3、兩種 join 的“坑”
? 由于HIVE中都是等值連接,在JOIN使用的時候,有兩種寫法在理論上是可以達(dá)到相同的效果的,但是由于實際情況的不一樣,子表中數(shù)據(jù)的差異導(dǎo)致結(jié)果也不太一樣。?
寫法一: left semi join
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | select ????????a.bucket_id, ????????a.search_type, ????????a.level1, ????????a.name1, ????????a.level2, ????????a.name2, ????????cast((a.alipay_fee)?as?double)?as?zhuliu_alipay, ????????cast(0?as?double)?as?total_alipay ????????from?tmall_data_fdi_search_zhuliu_alipay_cocerage_bucket_1 a ?????left?semi?join ?????tmall_data_fdi_dim_main_auc b ?????on?(a.level2 = b.cat_id2 ?????????and?a.brand_id = b.brand_id ?????????and?b.cat_id2 > 0 ?????????and?b.brand_id > 0 ?????????and?b.max_price = 0 ?????) |
結(jié)果是 3121 條
寫法二: join on
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | select ????????a.bucket_id, ????????a.search_type, ????????a.level1, ????????a.name1, ????????a.level2, ????????a.name2, ????????cast((a.alipay_fee)?as?double)?as?zhuliu_alipay, ????????cast(0?as?double)?as?total_alipay ????????from?tmall_data_fdi_search_zhuliu_alipay_cocerage_bucket_1 a ?????join???tmall_data_fdi_dim_main_auc b ?????on?(a.level2 = b.cat_id2 ?????????and?a.brand_id = b.brand_id) ??where??b.cat_id2 > 0 ?????????and?b.brand_id > 0 ?????????and?b.max_price = 0 |
結(jié)果是 3142?條
由于子表(tmall_data_fdi_dim_main_auc)中存在重復(fù)的數(shù)據(jù),當(dāng)使用JOIN ON的時候,A,B表會關(guān)聯(lián)出兩條記錄,應(yīng)為ON上的條件符合;?
而是用LEFT SEMI JOIN 當(dāng)A表中的記錄,在B表上產(chǎn)生符合條件之后就返回,不會再繼續(xù)查找B表記錄了,所以如果B表有重復(fù),也不會產(chǎn)生重復(fù)的多條記錄。 如果B中沒有A也沒有哦
大多數(shù)情況下 JOIN ON 和 left semi on 是對等的,但是在上述情況下會出現(xiàn)重復(fù)記錄,導(dǎo)致結(jié)果差異,所以大家在使用的時候最好能了解這兩種方式的原理,避免掉“坑”。
總結(jié)
以上是生活随笔為你收集整理的left join 和 left semi join区别 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全球与中国数据标注软件市场深度研究分析报
- 下一篇: 第44章 通过GoogleAuthent