hive的優化

舊時光中的旅人發表於2020-12-27

1.使用Explain命令,檢視執行計劃,不會真正的執行,可以詳細的檢視sql執行的每一個細節。

2.fetch指的是hive在對某些情況下可以不是用mapreduce,在配置檔案中修改hive.fetch.task.conversion,在屬性修改為more以後全域性查詢,欄位查詢,limit等都不走mapreduce。

3.大多數的hadoopjob需要hadoop完整的效能,對於一些資料量非常小的hive任務,觸發查詢執行計劃的時間比實際執行job消耗的時間還多。Hive可以通過本地模式在單臺機器上處理所有的任務,處理小的資料集,時間被明顯縮短。設定hive.exec.mmode.local.auto為true。

 

  1. 表的優化:

1.小表join大表

  1. 小表Join大表,設定選擇mapjoin set hive.auto.convert.join=true;
  2. 設定大表小表的閾值,set hive.mapjoin.smalltable.filesize=2500000;
  3. 這樣兩個表在Join的時候會先mapjoin小表。
  1. 大表join大表

按空key進行過濾:

有時表的資料很大,key對應的資料太多,而相同的key會傳送到相同的reduce上,從而導致記憶體不夠。我們需要對key進行分析,大多是異常資料。例如key對應的欄位為空。

空key過濾使用場景:

  1. 非inner join
  2. 不需要欄位為Null的

先join再過濾 ,先過濾再join(效率高)

空key的轉換:

有時空key是正常的資料,而且我們需要這種資料,此時我們可以對錶中key的欄位賦隨機值,使得資料分佈在不同的reduce中。

例子:

不進行隨機:

insert overwrite table jointable

select n.* from nullidtable n left join bigtable b on n.id = b.id;

 

進行隨機:

insert overwrite table jointable

select n.* from nullidtable n full join bigtable o on nvl(n.id,rand()) = o.id;

3.分桶表 SMB(Sort Merge Bucket join)

建立分桶表,按id進行分桶,提高了併發,到最後再把分桶的結果進行合併,能極大的提高速度。

5.group by

預設情況下map階段同一個key傳送的一個reduce,當key的資料過多時就造成了資料傾斜。這種情況下不是的所有的聚合都在reduce完成,也可以在map端進行部分聚合,在reduce端在合併。

  1. 開啟Map端引數合併
  2. Setv hive.map.aggr=true
  3. 設定聚合的條數

set hive.groupby.mapaggr.checkinterval=10000

  1. 有資料傾斜時進行負載均衡

Set hive.groupby.skewindata=true

在設定為true的時候生成的查詢計劃會有兩個mrjob,第一個按key reduce進行預聚合,第二個在根據key進行合併完成聚合。

6.Count(distinct)去重統計

慎用distinct,無論設定多少個reduce結果都會放在一個reduce,資料太大,會造成oom。這種情況可以使用group by代替,再把結果作為子表,再次查詢去重,但是要注意groupby造成的資料傾斜的問題。

  1. 笛卡爾積

在沒有關聯條件或者關聯條件無效的on時,hive只能用一個reduce來完成笛卡爾積。

  1. 行列過濾

列處理:

在查詢的時候,只拿到所需要的列,有分割槽用分割槽,少用select*

行處理:

在分割槽剪裁中,當使用外關聯時,如果將副表的過濾條件寫在 Where 後面,那麼就會先全表關聯,之後再過濾。

分為先關聯再過濾,先過濾在關聯(效果會調高)。

  1. 建立分割槽,和分桶表
  2. 合理設定map和reduce的數量。
  3. 複雜檔案增減map數

增加 map 的方法為:根據

computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M 公式, 調整 maxSize 最大值。讓maxSize 最大值低於 blocksize 就可以增加 map 的個數。

13.小檔案進行合併

在map執行前提前合併小檔案,減少map數:combinehiveinputformat具有合併小檔案的功能,(系統預設的格式),hiveinputformat沒有這功能。

可以在mapreduce結束時合併小檔案。

在map-only任務結束時合併小檔案的設定:預設true

Set hive.merge.mapfiles=true

在Map-reduce任務結束時合併小檔案預設false

Set hive.merge.mapfiles=true

合併檔案的大小預設是256m

Set hive.meger.size.per.task=268435456;

當輸出檔案的平均大小小於該值時,啟動一個獨立的mapreduce任務進行檔案merger

Set hive.meger.smallfiles.avgsize=16777216

  1. 合理設定reduce數
  1. 調整reduce個數方法一

每個reduce處理的資料量預設是256m

Hive.exex.reduces.bytes.per.reducer=256m

每個任務最大的reduce數,預設為1009

Hive.exex.reduces.max=1009

計算公式

N=min(引數2,總輸入量數/引數1)

  1. 調整reduce個數方法二。

在hadoop的mapred.xml檔案中修改

設定每個job的reduc個數

Set mapreduce.job.reduces=15

  1. 設定並行執行
  2. 嚴格模式

Hive可以通過設定防止一些危險的操作。

  1. 分割槽表不使用分割槽過濾。
  2. 使用orderby 沒有limit過濾
  3. 笛卡爾積
  1. jvm重用

Jvm的重用一般設定引數為10-20中間,jvm適合處理小的任務,因為啟動執行計劃的時間可能要大於執行job的時間,開始可以減少時間,如果是大的資料使用jvm重用會造成oom。

17.壓縮

 

相關文章