hive的儲存層依託於hdfs,hive的計算層依託於mapreduce,一般hive的執行效率主要取決於sql語句的執行效率,因此,hive的優化的核心思想是mapreduce的優化。
hive的sql語句在執行之前需要將sql語句轉換成mapreduce任務,因此需要了解具體的轉換過程,可以在sql語句中輸入如下命令檢視具體的執行計畫。
--檢視執行計畫,新增extended關鍵字可以檢視更加詳細的執行計畫
explain
[extended
] query
hive的某些sql語句需要轉換成mapreduce的操作,某些sql語句就不需要轉換成mapreduce操作,但是需要注意,理論上來說,所有的sql語句都需要轉換成mapreduce操作,只不過hive在轉換sql語句的過程中會做部分優化,使某些簡單的操作不再需要轉換成mapreduce,例如:
(1)select 僅支援本表字段
(2)where僅對本表字段做條件過濾
--檢視hive的資料抓取策略
set hive.
fetch
.task.conversion=none/more;
類似於mapreduce的操作,hive的執行也分為本地模式和集群模式,在開發階段可以選擇使用本地執行,提高sql語句的執行效率,驗證sql語句是否正確。
--設定本地模式
set hive.
exec
.mode
.local
.auto=
true
;
注意:要想使用hive的本地模式,載入資料檔案大小不能超過128m,如果超過128m,就算設定了本地模式,也會按照集群模式執行。
--設定讀取資料量的大小限制
set hive.
exec
.mode
.local
.auto.inputbytes.max=
128m
在sql語句足夠複雜的情況下,可能在乙個sql語句中包含多個子查詢語句,且多個子查詢語句之間沒有任何依賴關係,此時,可以hive執行的並行度
--設定hive sql的並行度
set hive.
exec
.parallel=
true
;
注意:hive的並行度並不是無限增加的,在一次sql計算中,可以通過以下引數來設定並行的job的個數
--設定一次sql計算允許並行執行的job個數的最大值
set hive.
exec
.parallel.thread.number
hive中為了提高sql語句的執行效率,可以設定嚴格模式,充分利用hive的某些特點。
-- 設定hive的嚴格模式
set hive.mapred.
mode
=strict;
注意:當設定嚴格模式之後,會有如下限制:
(1)對於分割槽表,必須新增where對於分割槽欄位的條件過濾
(2)order by語句必須包含limit輸出限制
(3)限制執行笛卡爾積的查詢
在編寫sql語句的過程中,很多情況下需要對資料進行排序操作,hive中支援多種排序操作適合不同的應用場景。
1、order by - 對於查詢結果做全排序,只允許有乙個reduce處理
(當資料量較大時,應慎用。嚴格模式下,必須結合limit來使用)
2、sort by - 對於單個reduce的資料進行排序
3、distribute by - 分割槽排序,經常和sort by結合使用
4、cluster by - 相當於 sort by + distribute by
(cluster by不能通過asc、desc的方式指定排序規則;
可通過 distribute by column sort by column asc|desc 的方式)
1、hive 在多個表的join操作時盡可能多的使用相同的連線鍵,這樣在轉換mr任務時會轉換成少的mr的任務。
2、手動map join:在map端完成join操作
--sql方式,在sql語句中新增mapjoin標記(mapjoin hint)
select
/*+ mapjoin(smalltable) */ smalltable.
key, bigtable.
value
from smalltable join bigtable on smalltable.
key= bigtable.
key;
3、開啟自動的map join
--通過修改以下配置啟用自動的mapjoin:
set hive.auto.
convert
.join
=true
;--(該引數為true時,hive自動對左邊的表統計量,如果是小表就加入記憶體,即對小表使用map join)
hive.mapjoin.smalltable.filesize;
--(大表小表判斷的閾值,如果表的大小小於該值則會被載入到記憶體中執行)
hive.
ignore
.mapjoin.hint;
--(預設值:true;是否忽略mapjoin hint 即mapjoin標記)
4、大表join大表
(1)空key過濾:有時join超時是因為某些key對應的資料太多,而相同key對應的資料都會傳送到相同的reducer上,從而導致記憶體不夠。此時我們應該仔細分析這些異常的key,很多情況下,這些key對應的資料是異常資料,我們需要在sql語句中進行過濾。
(2)空key轉換:有時雖然某個key為空對應的資料很多,但是相應的資料不是異常資料,必須要包含在join的結果中,此時我們可以表a中key為空的字段賦乙個隨機的值,使得資料隨機均勻地分不到不同的reducer上
hive的某些sql操作可以實現map端的聚合,類似於mr的combine操作
--通過設定以下引數開啟在map端的聚合:
set hive.map.aggr=
true
;--map端group by執行聚合時處理的多少行資料(預設:100000)
hive.groupby.mapaggr.checkinterval:
--進行聚合的最小比例(預先對100000條資料做聚合,若聚合之後的資料量/100000的值大於該配置0.5,則不會聚合)
hive.map.aggr.
hash
.min.reduction:
--map端聚合使用的記憶體的最大值
hive.map.aggr.
hash
.percentmemory:
--是否對groupby產生的資料傾斜做優化,預設為false
hive.groupby.skewindata
hive在操作的時候,如果檔案數目小,容易在檔案儲存端造成壓力,給hdfs造成壓力,影響效率
--設定合併屬性
--是否合併map輸出檔案:
set hive.
merge
.mapfiles=
true
--是否合併reduce輸出檔案:
set hive.
merge
.mapredfiles=
true
;--合併檔案的大小:
set hive.
merge
.size.per.task=
256*
1000
*1000
--map數量相關的引數
--乙個split的最大值,即每個map處理檔案的最大值
set mapred.max.split.size
--乙個節點上split的最小值
set mapred.min.split.size.per.node
--乙個機架上split的最小值
set mapred.min.split.size.per.rack
--reduce數量相關的引數
--強制指定reduce任務的數量
set mapred.reduce.tasks
--每個reduce任務處理的資料量
set hive.
exec
.reducers.bytes.per.reducer
--每個任務最大的reduce數
set hive.
exec
.reducers.max
/*
適用場景:
1、小檔案個數過多
2、task個數過多
缺點: 設定開啟之後,task插槽會一直占用資源,不論是否有task執行,直到所有的task即整個job全部執行完成時,才會釋放所有的task插槽資源!
*/set mapred.job.reuse.jvm.num.tasks=n;
--(n為task插槽個數)
hive 優化策略
explain 解釋執行計畫 通過explain命令,可以檢視hive語句的操作情況,是否為慢查詢,是否走索引,一目了然 explain select sum from table name 動態分割槽調整 hive.exec.dynamic.partition.mode strict 預設是str...
Hive效能優化大全
核心思想 是將hive程式當做mapreduce程式進行優化 hive中sql語句轉化為mapreduce的過程,整個編譯過程分為6個階段 1 antlr定義sql的語法規則,完成sql詞法,語法解析,將sql轉化為 抽象語法樹ast tree。2 遍歷抽象語法樹ast tree,抽象出查詢的基本組...
Hive 實戰優化策略
2018 06 14更新 更新8 hive 在大資料執行時,真的是很慢,跑一張表經常就是跑幾個小時,一天下來跑不了幾張表,通過一段時間學習,總結幾個常用的hive 優化方法,希望對新手有點幫助,我也是新手,部落格存在問題的地方,請大家批評指正,共同學習 進步,謝謝!hive f 路徑 filenam...