Hive 如何使用mapjoin


Hive 如何使用mapjoin

轉載:原文鏈接 https://www.jianshu.com/p/b52466e93226  https://www.cnblogs.com/1130136248wlxk/articles/5692594.html

hive mapjoin使用

今天遇到一個hive的問題,如下hive sql:

 

select f.a,f.b from A t join B f  on ( f.a=t.a and f.ftime=20110802)  

該語句中B表有30億行記錄,A表只有100行記錄,而且B表中數據傾斜特別嚴重,有一個key上有15億行記錄,在運行過程中特別的慢,而且在reduece的過程中遇有內存不夠而報錯。

 

為了解決用戶的這個問題,考慮使用mapjoin,mapjoin的原理:

MAPJION會把小表全部讀入內存中,在map階段直接拿另外一個表的數據和內存中表數據做匹配,由於在map是進行了join操作,省去了reduce運行的效率也會高很多

這樣就不會由於數據傾斜導致某個reduce上落數據太多而失敗。於是原來的sql可以通過使用hint的方式指定join時使用mapjoin。

select /*+ mapjoin(A)*/ f.a,f.b from A t join B f  on ( f.a=t.a and f.ftime=20110802) 

再運行發現執行的效率比以前的寫法高了好多。

 

mapjoin還有一個很大的好處是能夠進行不等連接的join操作,如果將不等條件寫在where中,那么mapreduce過程中會進行笛卡爾積,運行效率特別低,如果使用mapjoin操作,在map的過程中就完成了不等值的join操作,效率會高很多。

例子:

select A.a ,A.b from A join B where A.a>B.a

 

簡單總結一下,mapjoin的使用場景:

1. 關聯操作中有一張表非常小

2.不等值的鏈接操作

MapJoin是Hive的一種優化操作,其適用於小表JOIN大表的場景,由於表的JOIN操作是在Map端且在內存進行的,所以其並不需要啟動Reduce任務也就不需要經過shuffle階段,從而能在一定程度上節省資源提高JOIN效率

簡單總結一下,mapjoin的使用場景:

1. 關聯操作中有一張表非常小

2.不等值的鏈接操作

 

具體使用:

方法一:

在Hive0.11前,必須使用MAPJOIN來標記顯示地啟動該優化操作,由於其需要將小表加載進內存所以要注意小表的大小

SELECT/*+ MAPJOIN(smalltable)*/.key,valueFROMsmalltableJOINbigtableONsmalltable.key=bigtable.key

方法二:

在Hive0.11后,Hive默認啟動該優化,也就是不在需要顯示的使用MAPJOIN標記,其會在必要的時候觸發該優化操作將普通JOIN轉換成MapJoin,可以通過以下兩個屬性來設置該優化的觸發時機

hive.auto.convert.join

默認值為true,自動開戶MAPJOIN優化

hive.mapjoin.smalltable.filesize

默認值為2500000(25M),通過配置該屬性來確定使用該優化的表的大小,如果表的大小小於此值就會被加載進內存中

 

注意:使用默認啟動該優化的方式如果出現默名奇妙的BUG(比如MAPJOIN並不起作用),就將以下兩個屬性置為fase手動使用MAPJOIN標記來啟動該優化

hive.auto.convert.join=false(關閉自動MAPJOIN轉換操作)

hive.ignore.mapjoin.hint=false(不忽略MAPJOIN標記)

 

對於以下查詢是不支持使用方法二(MAPJOIN標記)來啟動該優化的

select/*+MAPJOIN(smallTableTwo)*/idOne, idTwo, valueFROM  ( select/*+MAPJOIN(smallTableOne)*/idOne, idTwo, valueFROM    bigTable JOINsmallTableOneon(bigTable.idOne= smallTableOne.idOne)                                                 

  ) firstjoin                                                           

  JOIN                                                               

  smallTableTwo ON(firstjoin.idTwo=smallTableTwo.idTwo)

但是,如果使用的是方法一即沒有MAPJOIN標記則以上查詢語句將會被作為兩個MJ執行,進一步的,如果預先知道表大小是能夠被加載進內存的,則可以通過以下屬性來將兩個MJ合並成一個MJ

hive.auto.convert.join.noconditionaltask:Hive在基於輸入文件大小的前提下將普通JOIN轉換成MapJoin,並是否將多個MJ合並成一個

hive.auto.convert.join.noconditionaltask.size:多個MJ合並成一個MJ時,其表的總的大小須小於該值,同時hive.auto.convert.join.noconditionaltask必須為true

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM