核心思想:是將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;是否在map端執行combine(大表小表判斷的閾值,如果表的大小小於該值則會被載入到記憶體中執行)
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端的聚合:
set hive.map.aggr=true;
hive.groupby.mapaggr.checkinterval:每個小檔案會啟動乙個map任務,浪費資源;map端group by執行聚合時處理的多少行資料(預設:100000)
hive.map.aggr.hash.min.reduction:
進行聚合的最小比例(預先對100000條資料做聚合,若聚合之後的資料量/100000的值大於該配置0.5,則不會聚合)
檔案數目小,容易在檔案儲存端造成壓力,給hdfs造成壓力,影響效率.;
將map和reduce的小檔案進行合併,大於256m後不再參與合併;
設定合併屬性資料量小的時候無所謂,資料量大的情況下,由於count distinct操作需要用乙個reduce task來完成,這乙個reduce需要處理的資料量太大,就會導致整個job很難完成,一般count distinct使用先group by再count的方式替換。是否合併map輸出檔案:hive.merge.mapfiles=true
是否合併reduce輸出檔案:hive.merge.mapredfiles=true;
合併檔案的大小:hive.merge.size.per.task=256*1000*1000
1)、map數量相關的引數
mapred.max.split.size
乙個split的最大值,即每個map處理檔案的最大值2)、reduce數量相關的引數乙個機架上split的最小值
mapred.min.split.size.per.rack
乙個節點上split的最小值
mapred.min.split.size.per.node
乙個split的最大值,即每個map處理檔案的最大值
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...