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(长按后点识别图中二维码):