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

7-hive优化