hive 常见调优方法:
-
0.11前版本开启MapJoin,之后的版本默认开启
MapJoin是Hive的一种优化操作,其适用于小表JOIN大表的场景,由于表的JOIN操作是在Map端且在内存进行的,所以其并不需要启动Reduce任务也就不需要经过shuffle阶段,从而能在一定程度上节省资源提高JOIN效率
-
行列过滤
列处理:在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);
-
采用分桶技术
-
采用分区技术
-
合理设置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(几百万记录)的数据,效率肯定会好很多。
-
合理设置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,就会有多少个输出文件,如果生成了很多个小文件这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;
为避免设置无效 要检查是否使用了group by,是否禁用了Order by ,是否有笛卡尔积。
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