hive查詢優化總結

2021-06-26 19:35:13 字數 3571 閱讀 1448

hive查詢優化總結

儲存,學習,分享

join查詢操作的基本原則:應該將條目少的表/子查詢放在 join 操作符的左邊。原因是在 join 操作的 reduce 階段,位於 join 操作符左邊的表的內容會被載入進記憶體,將條目少的表放在左邊,可以有效減少發生記憶體溢位錯誤的機率。

join查詢操作中如果存在多個join,且所有參與join的表中其參與join的key都相同,則會將所有的join合併到乙個mapred程式中。

案例:select a.val, b.val, c.val from a join b on (a.key = b.key1) join c on (c.key = b.key1)  在乙個mapre程式中執行join

select a.val, b.val, c.val from a join b on (a.key = b.key1) join c on (c.key = b.key2)   在兩個mapred程式中執行join

map join的關鍵在於join操作中的某個表的資料量很小,案例:

select /*+ mapjoin(b) */ a.key, a.value

from a join b on a.key = b.key 

mapjoin 的限制是無法執行a full/right outer join b,和map join相關的hive引數:hive.join.emit.interval  hive.mapjoin.size.key  hive.mapjoin.cache.numrows

由於join操作是在where操作之前執行,所以當你在執行join時,where條件並不能起到減少join資料的作用;案例:

select a.val, b.val from a left outer join b on (a.key=b.key)

where a.ds='2009-07-07' and b.ds='2009-07-07'

最好修改為:

select a.val, b.val from a left outer join b

on (a.key=b.key and b.ds='2009-07-07' and a.ds='2009-07-07')

在join操作的每乙個mapred程式中,hive都會把出現在join語句中相對靠後的表的資料stream化,相對靠前的變的資料快取在記憶體中。當然,也可以手動指定stream化的表:select /*+ streamtable(a) */ a.val, b.val, c.val from a join b on (a.key = b.key1) join c on (c.key = b.key1)

map端聚合,首先在map端進行初步聚合,最後在reduce端得出最終結果,相關引數:

· hive.map.aggr = true是否在 map 端進行聚合,預設為 true

· hive.groupby.mapaggr.checkinterval = 100000在 map 端進行聚合操作的條目數目

資料傾斜聚合優化,設定引數hive.groupby.skewindata = true,當選項設定為 true,生成的查詢計畫會有兩個 mr job。第乙個 mr job 中,map 的輸出結果集合會隨機分布到 reduce 中,每個 reduce 做部分聚合操作,並輸出結果,這樣處理的結果是相同的 group by key 有可能被分發到不同的 reduce 中,從而達到負載均衡的目的;第二個 mr job 再根據預處理的資料結果按照 group by key 分布到 reduce 中(這個過程可以保證相同的 group by key 被分布到同乙個 reduce 中),最後完成最終的聚合操作。

檔案數目過多,會給 hdfs 帶來壓力,並且會影響處理效率,可以通過合併 map 和 reduce 的結果檔案來消除這樣的影響:

· hive.merge.mapfiles = true是否和並 map 輸出檔案,預設為 true

· hive.merge.mapredfiles = false是否合併 reduce 輸出檔案,預設為 false

· hive.merge.size.per.task = 256*1000*1000合併檔案的大小

通過left outer join進行查詢,(假設b表中包含另外的乙個字段 key1 

select a.key from a left outer join b on a.key=b.key where b.key1 is null

通過left semi join 實現 in

select a.key, a.val from a left semi join b on (a.key = b.key)

left semi join 的限制:join條件中右邊的表只能出現在join條件中。

order by 實現全域性排序,乙個reduce實現,效率低

sort by 實現部分有序,單個reduce輸出的結果是有序的,效率高,通常和distribute by關鍵字一起使用(distribute by關鍵字 可以指定map 到 reduce端的分發key)

cluster by col1 等價於distribute by col1 sort by col1

hive中的每個分割槽都對應hdfs上的乙個目錄,分割槽列也不是表中的乙個實際的字段,而是乙個或者多個偽列,在表的資料檔案中實際上並不儲存分割槽列的資訊與資料。partition關鍵字中排在前面的為主分割槽(只有乙個),後面的為副分割槽

靜態分割槽:靜態分割槽在載入資料和使用時都需要在sql語句中指定

案例:(stat_date='20120625',province='hunan')

動態分割槽:使用動態分割槽需要設定hive.exec.dynamic.partition引數值為true,預設值為false,在預設情況下,hive會假設主分割槽時靜態分割槽,副分割槽使用動態分割槽;如果想都使用動態分割槽,需要設定set hive.exec.dynamic.partition.mode=nostrick,預設為strick

案例:(stat_date='20120625',province)

hive支援在group by時對同一列進行多次distinct操作,卻不支援在同乙個語句中對多個列進行distinct操作。

注意事項:在使用自定義的mapred指令碼時,關鍵字map reduce 是語句select transform ( ... )的語法轉換,並不意味著使用map關鍵字時會強制產生乙個新的map過程,使用reduce關鍵字時會產生乙個red過程。

自定義的mapred指令碼可以是hql語句完成更為複雜的功能,但是效能比hql語句差了一些,應該盡量避免使用,如有可能,使用udtf函式來替換自定義的mapred指令碼

udtf將單一輸入行轉化為多個輸出行,並且在使用udtf時,select語句中不能包含其他的列,udtf不支援巢狀,也不支援group by 、sort by等語句。如果想避免上述限制,需要使用lateral view語法,案例:

select a.timestamp, b.*

其中,get_json_object為udf函式,json_tuple為udtf函式。

udtf函式在某些應用場景下可以大大提高hql語句的效能,如需要多次解析json或者xml資料的應用場景。

count和sum函式可能是在hql語句中使用的最為頻繁的兩個聚合函式了,但是在hive中count函式在計算distinct value時支援加入條件過濾。

Hive查詢表的優化總結

一 小表join大表 1 小表在左邊 但是新版本已經沒區別 2 開啟mapjoin 3 先過濾再join 二 大表join大表 1 空key過濾 2 空key處理 3 先過濾再join 三 group by 設定引數,使之執行兩個 mr job 第乙個mr job中,map的輸出結果會隨機分布到re...

Hive查詢優化

害,最近組裡有個妹子不是很懂sql,一查就等好長時間,看的我十分揪心,算了,寫幾個常見的hive查詢優化叭。1.條目少的表或者子查詢放在join左邊,因為join左邊會讀入記憶體 select a.val b.val from a 條目少 join b on a.key b.key 2.join 操...

Hive查詢優化

1.先過濾,再查詢,因為每次生成中間表都會儲存到linux磁碟上 記住 不是hdfs 2.注意資料傾斜 傾斜的原因是reduce端資料的大量富集,可適度增加reduce 會著開啟 reduce自己判斷 某一比較大 自己再分開點.也就是合理設定 reduce數量 hive.exec.reducers....