如果不指定MapJoin或者不符合MapJoin的條件伪阶,那么Hive解析器會(huì)將Join操作轉(zhuǎn)換成Common Join腺办,即:在Reduce階段完成join腕扶。容易發(fā)生數(shù)據(jù)傾斜藻雌〈菩可以用MapJoin把小表全部加載到內(nèi)存在map端進(jìn)行join,避免reducer處理胯杭。
1驯杜、開(kāi)啟MapJoin參數(shù)設(shè)置
(1)設(shè)置自動(dòng)選擇Mapjoin
//默認(rèn)為true
set hive.auto.convert.join = true;
(2)大表小表的閥值設(shè)置(默認(rèn)25M一下認(rèn)為是小表):
set hive.mapjoin.smalltable.filesize=25000000;
2、MapJoin工作機(jī)制
首先是Task A做个,它是一個(gè)Local Task(在客戶端本地執(zhí)行的Task)鸽心,負(fù)責(zé)掃描小表b的數(shù)據(jù),將其轉(zhuǎn)換成一個(gè)HashTable的數(shù)據(jù)結(jié)構(gòu)居暖,并寫(xiě)入本地的文件中顽频,之后將該文件加載到DistributeCache中。
接下來(lái)是Task B太闺,該任務(wù)是一個(gè)沒(méi)有Reduce的MR糯景,啟動(dòng)MapTasks掃描大表a,在Map階段,根據(jù)a的每一條記錄去和DistributeCache中b表對(duì)應(yīng)的HashTable關(guān)聯(lián)跟束,并直接輸出結(jié)果莺奸。
由于MapJoin沒(méi)有Reduce,所以由Map直接輸出結(jié)果文件冀宴,有多少個(gè)Map Task灭贷,就有多少個(gè)結(jié)果文件。
案例實(shí)操
(1)開(kāi)啟Mapjoin功能
//默認(rèn)為true
hive > set hive.auto.convert.join = true;
(2)執(zhí)行小表JOIN大表語(yǔ)句
hive > insert overwrite table jointable
select b.id, b.time, b.uid, b.keyword, b.url_rank, b.click_num, b.click_url
from smalltable s
join bigtable b
on s.id = b.id;
Time taken: 24.594 seconds
(3)執(zhí)行大表JOIN小表語(yǔ)句
hive > insert overwrite table jointable
select b.id, b.time, b.uid, b.keyword, b.url_rank, b.click_num, b.click_url
from bigtable b
join smalltable s
on s.id = b.id;
Time taken: 24.315 seconds