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(長按後點識別圖中二維碼):