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....