桶的概念: https://blog.csdn.net/bigkeen/article/details/51318997
1 bucket mapjoin
1.1 條件
1) set hive.optimize.bucketmapjoin = true;
2) 一個表的bucket數是另一個表bucket數的整數倍
3) bucket列 == join列
4) 必須是應用在map join的場景中
1.2 注意
1)如果表不是bucket的,只是做普通join。
2 SMB join (針對bucket mapjoin 的一種優化)
2.1 條件
1)
set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
set hive.auto.convert.sortmerge.join.noconditionaltask=true;
2) 小表的bucket數=大表bucket數
3) Bucket 列 == Join 列 == sort 列
4) 必須是應用在bucket mapjoin 的場景中
2.2 注意
hive並不檢查兩個join的表是否已經做好bucket且sorted,需要用戶自己去保證join的表,否則可能數據不正確。有兩個辦法
1)hive.enforce.sorting 設置為true。
2)手動生成符合條件的數據,通過在sql中用distributed c1 sort by c1 或者 cluster by c1
表創建時必須是CLUSTERED且SORTED,如下
create table test_smb_2(mid string,age_id string)
CLUSTERED BY(mid) SORTED BY(mid) INTO 500 BUCKETS;
SMB(Sort-Merge-Buket) Join
- 場景:
-
大表對小表應該使用MapJoin,但是如果是大表對大表,如果進行shuffle,那就要人命了啊,第一個慢不用說,第二個容易出異常,既然是兩個表進行join,肯定有相同的字段吧。
-
tb_a - 5億(按排序分成五份,每份1億放在指定的數值范圍內,類似於分區表)
a_id
100001 ~ 110000 - bucket-01-a -1億
110001 ~ 120000
120001 ~ 130000
130001 ~ 140000
140001 ~ 150000 -
tb_b - 5億(同上,同一個桶只能和對應的桶內數據做join)
b_id
100001 ~ 110000 - bucket-01-b -1億
110001 ~ 120000
120001 ~ 130000
130001 ~ 140000
140001 ~ 150000 -
注:實際生產環境中,一天的數據可能有50G(舉例子可以把數據弄大點,比如說10億分成1000個bucket)。
- 原理:
-
在運行SMB Join的時候會重新創建兩張表,當然這是在后台默認做的,不需要用戶主動去創建,如下所示:
-
設置(默認是false):
set hive.auto.convert.sortmerge.join=true set hive.optimize.bucketmapjoin=true; set hive.optimize.bucketmapjoin.sortedmerge=true;
- 總結:
-
其實在寫程序的時候,我們就可以知道哪些是大表哪些是小表,注意調優。