Hive效能優化大全

2021-09-19 23:03:52 字數 3971 閱讀 3779

核心思想:是將hive程式當做mapreduce程式進行優化;

hive中sql語句轉化為mapreduce的過程,整個編譯過程分為6個階段:

1).antlr定義sql的語法規則,完成sql詞法,語法解析,將sql轉化為 抽象語法樹ast tree。

2).遍歷抽象語法樹ast tree,抽象出查詢的基本組成單元 queryblock查詢塊。

3).遍歷queryblock,翻譯為執行操作樹operatortree。

4).邏輯層優化器進行operatortree變換,合併不必要的reducesinkoperator,減少shuffle資料量。

5).遍歷operatortree,翻譯為mapreduce任務。

6).物理層優化器進行mapreduce任務的變換,生成最終的執行計畫。

在hive命令列輸入:explain extended select count(*) from bigdata_user;

可以檢視該sql執行的整個過程。

1).集群模式:需要先將本地程式打成jar包,上傳集群,如果執行出錯,需要繼續修改上傳,在執行jar包,迴圈往復,影響開發效率。

2).本地模式:在hive中執行 set hive.exec.mode.local.auto=true;

只能在測試和開發環境進行,並且限制輸入檔案的大小不能超過128m,如果大於該配置,仍會以集群方式執行。對於小資料執行時間可以明顯被縮短。

一次sql計算中允許並行執行的job個數的最大值,hive會將乙個查詢轉化成乙個或者多個階段。這樣的階段可以是mapreduce階段、抽樣階段、合併階段、limit階段。由於job包含多個階段,而這些階段並非完全互相依賴,所以可以啟用並行執行,縮短整個job的執行時間(硬體資源充足,預設並行度是8)

設定引數:hive.exec.parallel.number

設定引數為:

set hive.mapred.mode = strict;

1)、笛卡爾積查詢:join查詢不使用on語句而是使用where語句

關係型資料庫的執行優化器可以高效地將where語句轉化成on語句,hive並不會執行這種優化。

2)、查詢沒有選擇分割槽:對於分割槽表,where語句中無分割槽字段過濾條件

不允許使用者掃瞄所有分割槽,因為分割槽表通常資料量巨大,沒有限制分割槽的查詢可能會消耗巨大資源。

3)、order by沒有limit語句:

order by 為了執行排序過程,會將所有的結果資料分發到同乙個reducer中進行處理,增加limit語句可以防止reducer額外執行很長一段時間。

4)、int型別資料與string和double型別比較

order by :對於查詢結果做全排序,只允許有乙個reduce處理 ,會造成資料傾斜, 一般不建議使用。嚴格模式下,必須結合limit來使用。

sort by :對於單個reduce的資料進行排序,分區內資料有序。

distribute by: 分割槽排序,分區間有序。經常和sort by結合使用

(distribute by column sort by column asc|desc的方式)

cluster by: sort by+distribute by,無法指定公升序和降序規則。

如果不指定mapjoin或者不符合mapjoin的條件,那麼hive解析器會預設把執行common join,即在reduce階段完成join。整個過程包含map、shuffle、reduce階段。map join:在map端完成join,沒有了shuffle,就沒有reduce。節省查詢時間。

1)、sql方式,在sql語句中新增mapjoin標記(mapjoin hint)

語法:select  /*+ mapjoin(smalltable) */  smalltable.key,  bigtable.value

from  smalltable  join  bigtable  on  smalltable.key  =  bigtable.key;

2)、開啟自動的mapjoin

通過修改以下配置啟用自動的mapjoin:

set hive.auto.convert.join = true;

(該引數為true時,hive自動對左邊的表統計量,如果是小表就加入記憶體,即對小表使用map join)

hive.mapjoin.smalltable.filesize; 

(大表小表判斷的閾值,如果表的大小小於該值則會被載入到記憶體中執行)

hive.ignore.mapjoin.hint;

(預設值:true;是否忽略mapjoin hint 即mapjoin標記)

hive.auto.convert.join.noconditionaltask;

(預設值:true;將普通的join轉化為普通的mapjoin時,是否將多個mapjoin轉化為乙個mapjoin)

hive.auto.convert.join.noconditionaltask.size;

(將多個mapjoin轉化為乙個mapjoin時,其表的最大值)

是否在map端執行combine

通過設定以下引數開啟在map端的聚合:

set hive.map.aggr=true;

hive.groupby.mapaggr.checkinterval:

map端group by執行聚合時處理的多少行資料(預設:100000)

hive.map.aggr.hash.min.reduction:

進行聚合的最小比例(預先對100000條資料做聚合,若聚合之後的資料量/100000的值大於該配置0.5,則不會聚合)

每個小檔案會啟動乙個map任務,浪費資源;

檔案數目小,容易在檔案儲存端造成壓力,給hdfs造成壓力,影響效率.;

將map和reduce的小檔案進行合併,大於256m後不再參與合併;

設定合併屬性

是否合併map輸出檔案:hive.merge.mapfiles=true

是否合併reduce輸出檔案:hive.merge.mapredfiles=true;

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

資料量小的時候無所謂,資料量大的情況下,由於count distinct操作需要用乙個reduce task來完成,這乙個reduce需要處理的資料量太大,就會導致整個job很難完成,一般count distinct使用先group by再count的方式替換。

1)、map數量相關的引數

mapred.max.split.size

乙個split的最大值,即每個map處理檔案的最大值

乙個機架上split的最小值

mapred.min.split.size.per.rack

乙個節點上split的最小值

mapred.min.split.size.per.node

乙個split的最大值,即每個map處理檔案的最大值

2)、reduce數量相關的引數

mapred.reduce.tasks

強制指定reduce任務的數量

hive.exec.reducers.bytes.per.reducer

每個reduce任務處理的資料量

hive.exec.reducers.max

每個任務最大的reduce數

預先申請了一些資源,避免了重複對資源的重複申請和銷毀工作(類似於執行緒池)

適用場景:

1)、小檔案數過多

2)、task個數過多

通過 set mapred.job.reuse.jvm.num.tasks=n; 來設定(n為task插槽個數)

缺點:設定開啟之後,task插槽會一直占用資源,不論是否有task執行,直到所有的task即整個job全部執行完成時,才會釋放所有的task插槽資源!

hive效能優化

向量查詢 vectorized query 每次處理資料時會將1024行資料組成乙個batch進行處理,而不是一行一行進行處理,這樣能夠顯著提高執行速度。可以通過設定 error error while processing statement failed execution error,retu...

hive的效能優化

計算資料優化主要有兩種思路,一種是減少處理資料量 一種是解決資料傾斜。資料傾斜一般可以分為三種 join階段資料傾斜 reduce階段資料傾斜 主要有兩種方式 1.2 join階段資料傾斜 是最常見的資料傾斜,按照表的大小和join方式的不同分別有多種處理方式。1.2.1 mapjoin 作用 適用...

Hive優化策略大全

hive的儲存層依託於hdfs,hive的計算層依託於mapreduce,一般hive的執行效率主要取決於sql語句的執行效率,因此,hive的優化的核心思想是mapreduce的優化。hive的sql語句在執行之前需要將sql語句轉換成mapreduce任務,因此需要了解具體的轉換過程,可以在sq...