Hive優化策略大全

2021-10-05 10:35:14 字數 4653 閱讀 1449

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