7-hive優化

1:按需取數

正確腳本:

select id from t_tab;

錯誤腳本:

select * from t_tab;

所以查詢數據如果只需要一兩個字段,儘量不要用*,如果表爲parquet列式存儲,能很好的體現性能。

 

2:在獲取含分區的大表數據時,當使用關聯時,如果將副表的過濾條件寫在Where後面,那麼就會先全表關聯,之後再過濾

select a.* from t_tab_a a join t_tab_b b on a.id = b.id where b.id <= 10;

優化後:

select a.*

  from t_tab_a a

  join t_tab_b b

    on a.id = b.id

   and b.id <= 10;

 

3:MapJoin通常用於一個很小的表和一個大表進行join的場景

select /*+ mapjoin(b) */

 a.*

  from t_tab_a a

  join t_tab_b b

    on a.id = b.id

   and b.id <= 10;

 

4:數據傾斜主要表現在,map /reduce程序執行時,reduce節點大部分執行完畢,但是有一個或者幾個reduce節點運行很慢,導致整個程序的處理時間很長,這是因爲某一個key的條數比其他key多很多(有時是百倍或者千倍之多),兩張表都很大,mapjoin不管用,巧用rand()來解決

select *

  from t_tab_a a

  left join (select *

               from t_tab_b) b

    on nvl(a.id, concat('try', rand())) =

       cast(b.id as string)

 

5:參數設置

5.1:壓縮數據文件,可減少map端讀取數據文件的時間,資源利用就少,同時可以節省空間。

set hive.exec.compress.output=true; --map/reduce 輸出壓縮,true:開啓壓縮,false:不開啓壓縮

set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  --指定輸出的壓縮格式(Gzip,BZip2,Snappy,LZO)

set hive.exec.compress.intermediate=true;    --是否開啓任務中間壓縮,true:開啓壓縮,false:不開啓壓縮

set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;--開啓中間壓縮格式

5.2:減少小文件,執行效率高

每個mr讀取文件是以256M爲最佳,如果文件大小小於這個值將合併文件,這種文件定義爲小文件,如果小文件數目過多,會給 HDFS 帶來壓力,並且會影響處理效率,可以通過合併 Map 和 Reduce 的結果文件來消除這樣的影響,常用參數設置如下:

set hive.merge.mapfiles;    --是否合併Map的輸出文件,true:合併,false:不合並

set hive.merge.mapredfiles;    --是否合併Reduce的輸出文件,true:合併,false:不合並

set mapred.max.split.size=100000000;

set mapred.min.split.size.per.node=100000000;

set mapred.min.split.size.per.rack=100000000;

set hive.input.format;    --表示合併小文件,默認值:org.apache.hadoop.hive.ql.io.CombineHiveInputFormat

set hive.merge.mapfiles = true    --在Map-only的任務結束時合併小文件

set hive.merge.mapredfiles = true    --在Map-Reduce的任務結束時合併小文件

set hive.merge.size.per.task = 268435456    --合併文件的大小

set hive.merge.smallfiles.avgsize=67108864   --當輸出文件的平均大小小於該值時,啓動一個獨立的map-reduce任務進行文件merge

5.3:mapjoin的巧用及慎用

mapjoin簡單說就是在map階段將小表讀入內存,順序掃描大表完成join,可以有效解決大表關聯小表由於數據分佈不均勻在reduce端數據傾斜問題。但mapjoin也需要慎用,由於是在內存關聯,關聯的表數據量過大,會導致內存溢出,執行報錯。常用參數設置如下:

set hive.auto.convert.join=true;    --是否啓用mapjoin方式,true:啓用,false:不啓用

set hive.ignore.mapjoin.hint;    --忽略mapjoin的hints,true:開啓提示,false:不開啓提示

set hive.auto.convert.join.noconditionaltask;    --啓用mapjoin方式時不使用mapjoin提示,true:開啓,false:不開啓

set hive.auto.convert.join.noconditionaltask.size;    --控制多大的表可以放進內存,默認10M

set hive.mapjoin.smalltable.filesize    --輸入表文件的mapjoin閾值,如果輸入文件的大小小於該值,則試圖將普通join轉化爲mapjoin,默認25MB

5.4:map端文件切割也好用

map端執行效率太慢,可以考慮增加map數,將map文件大小切割變小,達到增加map個數

set mapred.max.split.size=1000000,控制map文件大小,默認爲256M

更多技術文章請關注公衆號BLT328(長按後點識別圖中二維碼):

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章