hive 常见调优方法:

  1. 0.11前版本开启MapJoin,之后的版本默认开启
    MapJoin是Hive的一种优化操作,其适用于小表JOIN大表的场景,由于表的JOIN操作是在Map端且在内存进行的,所以其并不需要启动Reduce任务也就不需要经过shuffle阶段,从而能在一定程度上节省资源提高JOIN效率
  2. 行列过滤
    列处理:在SELECT中,只拿需要的列,如果有,尽量使用分区过滤,少用SELECT *。
    行处理:在分区剪裁中,当使用外关联时,只拿需要的分区,如果将副表的过滤条件写在Where后面,那么就会先全表关联,之后再过滤。
//过滤前
 SELECT a.id FROM bigtable a  LEFT JOIN ori b ON a.id = b.id  WHERE b.id <= 10;
 //过滤后
 SELECT a.id FROM ori a  LEFT JOIN bigtable b ON (b.id <= 10 AND a.id = b.id);
  1. 采用分桶技术
  2. 采用分区技术
  3. 合理设置map数
     减少map数:合并小文件
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

 set mapred.max.split.size=100000000;
 set mapred.min.split.size.per.node=100000000;
 set mapred.min.split.size.per.rack=100000000;
 前面三个参数确定合并文件块的大小,大于文件块大小128m的,按照128m来分隔,小于128m,大于100m的,按照100m来分隔,把那些小于100m的(包括小文件和分隔大文件剩下的)进行合并

增加map数

set mapred.reduce.tasks=10;
 create table t_1 as 
 select * from t 
 distribute by rand(123); 
 
 此时会将a表的记录,随机的分散到包含10个文件的t_1表中,再用t_1代替上面sql中的t表,则会用10个map任务去完成。
 每个map任务处理大于12M(几百万记录)的数据,效率肯定会好很多。
  1. 合理设置Reduce数
    reduce个数的设定极大影响任务执行效率,默认如果reduce的输入(map的输出)总大小不超过1G,那么只会有一个reduce任务;用了order by 则永远只有一个reduce
  • 增加
调整reduce个数方法一: 
 调整hive.exec.reducers.bytes.per.reducer参数的值;
 set hive.exec.reducers.bytes.per.reducer=500000000; (500M)
 select pt,count(1) from table where pt = '2019-01-01' group by pt; 这次有20个reduce
          
 调整reduce个数方法二; 
 set mapred.reduce.tasks = 10;
 select pt,count(1) from table where pt = '2019-01-01' group by pt;这次有10个reduce
  • 减少
set mapred.reduce.tasks= ;

启动和初始化reduce也会消耗时间和资源,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;

 ,是否有笛卡尔积。

        7.常用参数



SET hive.merge.mapfiles = true; -- 默认true,在map-only任务结束时合并小文件
SET hive.merge.mapredfiles = true; -- 默认false,在map-reduce任务结束时合并小文件(比如只有map的任务)
SET hive.merge.size.per.task = 268435456; -- 默认256M
SET hive.merge.smallfiles.avgsize = 16777216; -- 当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge