HIVESQL優化方法

2021-09-25 14:33:35 字數 2991 閱讀 1150

(這是我2年前總結的東西,當時是用華為paas平台的大資料集群的時候,因為我們公司分配的資源較少,自己總結的部分優化方法,如有不足,望大家指正)

1)set hive.map.aggr=true/false;

當使用聚合函式時會在ma階段進行聚合  效率更高同時消耗更多資源

2)當join表的時候有乙個大表時用mapjoin

select /*+ mapjoin(a) */ a.key,a,value,b,key,b.value from table_name_1 a join table_name_2 b on a.key=b.key;(a表為小表)

當其中的小表的資料量也非常大的時候,將小表上的資料分別分發到map上也是不小的資源開銷,而且mapjoin可能不支援這麼大的小表

這時候需要利用深層次的mapjoin進行處理 

比如select * from a join b on a.id=b.id; a為小表且a也非常大

則select /*+ mapjoin(a) */ * from a join b on a.id=b.id;這樣的語句依舊非常耗費資源 我們可以進行這樣的操作

select /*+ mapjoin(d) */ * from b join (select /*+ mapjoin(c) */ from (select distinct id from b) c join a on c.id=a.id) d on a.id=b.id;

先取大表的關聯欄位去重跟小表關聯 取小表的的字段 然後得出關聯後的小表記錄再去用mapjoin與大表關聯 這樣節省了集群的開銷。但是會加大sql書寫人員的難度

3)order by會對所有查詢結果進行一次全域性排序,會將所有資料傳給乙個reduce進行排序。當資料量級很大是,這個過程會非常慢

而sort by 會對每個reduce處理的資料進行區域性排序,這樣就大大提高了全域性排序的效率

4)set mapreduce.job.priority=high; 

改變佇列的優先順序(當佇列中沒有任務時)

5)使用本地模式★

set hive.exec.mode.local.auto=true;(設定本地模式,一般預設為false)

當提交任務量較小時會在本地區處理而不是在集群上去處理,大大減少了處理時間

當乙個job滿足以下條件時會啟用本地模式

job的資料大小引數必須小於 hive.exec.mode.local.auto.inputbytes.max  預設128m

job的map數必須小於引數 hive.exec.mode.local.auto.tasks.max   預設4

job的reduce數必須為1或者0

6)並行執行

set hive.exec.parallel=true;(預設是false)

當乙個sql會產生多個stage(即mr任務)   多個stage會逐步執行

當上述設定為true是就會並行執行其stage  提高效率

但是當多個stage之間存在依賴時還是會逐步執行

7)分割槽裁剪優化 

例如 select * from (select * from a) a where a.receive_day='xx' (a.receive_day為分割槽字段) 肯定不如將receive_day的限制分割槽放在子查詢內占用的資源少

設定 hive.optimize.pruner設定為true時hive會自動執行這種優化

8)hive.groupby.skewindata=true; 

當使用groupby或者distinct的時候 在執行第二個mapreduce預處理過程中會保證相同的 group by key 分布到同乙個reduce上面(如不設定會隨機分配),會提高效率

9)hive的union all(hive不支援union語法)

hive的union all 的優化只侷限於非巢狀迴圈,如select * from a unin all select * from b union all select * from c join d on c.id=d.id

上述語句會在hadoop上產生4個job任務  我們利用union all的特性 對其進行 insert overwrite table e select * from c join d and c.id=d.id;

select * from a union select * from b union all select * from e 這樣只會產生2個job  而如果只是單純的加括號進行巢狀的話還是會產生4個job任務

10)如果多個union all進行操作時且其資料量巨大,應該拆分成多個insert into 效率會提高大概50%

11)insert overwrite directory 'hdfs目錄' select * from table; 當次過程產生多個檔案的情況一般有2種情況 第一種是檔案過大,超過其限制的檔案快,集群會自動切割其分成檔案塊

第二種是由於其reduce過多導致,每個reduce產生乙個檔案,會生成許許多多的小檔案 甚至每個檔案的大小都不到1kb  這樣會使統計資料變得繁瑣

使用hive引數hive.merge.mapredfiles引數更改  是否合併reduce輸出檔案 預設是false

12)left semi join 

select a.* from a where a.id,a.type in (select id,type from b);這種方法在hive中是不可取的  需要通過left simi join來進行操作

select a.* from a left simi join b on a.id=b.id and a.type=b.type;

切記select和where中不能出現b表的字段 

hive sql優化整理

hive sql優化方法引數一些整理,方便快速查詢使用 1.map數量與reduce數量的控制 輸入檔案大小指實際檔案大小,與檔案格式textfile,orc等無關,壓縮的檔案格式會小很多設定引數要適當調整 map數量控制 set hive.input.format org.apache.hadoo...

hivesql 效率優化

1.group by 資料傾斜問題 hive是根據group by 的key進行資料分發的,某個key相同的資料太多的會被分發到乙個reducer上,key的資料分布不均勻會導致大量資料被shuffle到某個或者某些reducer上,出現嚴重的資料傾斜,使得資料計算變慢 配置任務引數 set hiv...

HiveSql效能優化

一 解決資料傾斜 1.過濾掉null部分 key值存在大量空欄位,會hash到同一reduce,造成reduce長尾,將null 值過濾掉 舉例 select user id from logs where statdate 20170815 where user id is not null 2....