一.hive的调优
1.本地模式:在单台机器上处理所有的任务,对于小数据集,执行时间明显缩短
set hive.exec.mode.local.auto=true;//开启本地mr
--设置local mr的最大输入数据量,当输入数据量小于这个值时采用local mr的方式,默认为128m
set hive.exec.mode.local.auto.inputbytes.max=51234560;
--设置local mr 最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式默认为4
set hive.exec.mode.local.auto.input.files.max=10;
空key的处理
1.1空key过滤(有时join超时是因为某些key对应的数据太多,相同的key会发送到相同的reducer上,从而导致内存不够)
利用子查询把非空的id跳出来 select * from 表名 where id is not null
1.2空key 的转换
set hive.exec.reducers.bytes.per.reducer=3123456每个reducer处理的数据量
不随机分配:
set hive.exec.reducers.bytes.per.reducer=32123456;
set mapreduce.job.reduces=7;
INSERT OVERWRITE TABLE jointable
SELECT a.*
FROM nullidtable a
LEFT JOIN ori b ON CASE WHEN a.id IS NULL THEN 'hive' ELSE a.id END = b.id;
随机分配:减轻reducer的压力
set hive.exec.reducers.bytes.per.reducer=32123456;
set mapreduce.job.reduces=7;
INSERT OVERWRITE TABLE jointable
SELECT a.*
FROM nullidtable a
LEFT JOIN ori b ON CASE WHEN a.id IS NULL THEN concat('hive', rand()) ELSE a.id END = b.id;
-
sql优化
2.1group by 默认情况下map阶段同一个key数据分发给一个reduce,当一个key数据过大时就倾斜了,并不是所有的聚合操作都需要在reduce端完成,很多聚合都可以在map端进行部分聚合,最后在reduce端得出最终结果。
开启map端聚合:set hive.map.aggr=true;默认为true;
在map端进行聚合操作的条目数目:set hive.groupby.mapaggr.checkinterval=100000;
有数据倾斜的时候进行负载均衡默认是false:set hive.groupby.skewindata=true;
2.2count (distinct):数量小时无所谓,数量大的情况下count distinct 操作需要一个reduce task来完成,这一个reduce需要处理的数据量太大,就会导致整个job很难完成,一般使用count distinct 先 group by 在count
2.3笛卡尔积:尽量避免笛卡尔积,既避免join的时候不加on条件或者无效的on条件,hive只能使用一个reducer来完成笛卡尔积 -
并行执行: hive会将一个查询转化成多个阶段,阶段可以是mapreduce阶段,抽样阶段,合并阶段、limit阶段,默认情况下hive一次回执行一个阶段。有些阶段可以并行执行;通过set hive.exec.parallel=true;set hive.exec.parallel.thread.number=16;同一个sql允许最大并行度,默认为8;
-
严格模式:set hive.mapred.mode=strict(nostrict);严格模式(非严格)严格模式下不能全表扫描 必须含有where字段;order by排序完必须加limit;动态分区必须非严格模式;
-
存储方式orc和压缩方式snappy
-
map的个数(hive):map的数量不是越多越好(许多小文件)可以通过设置参数设置
set mapred.max.split.size=112345600;--split最大值100m
set mapred.min.split.size.per.node=112345600;--一个节点上最小的split大小
set mapred.min.split.size.per.rack=112345600;--一个机架上最小的split大小
set hive.input.format=org.aparche.hadoop.hive.ql.io.CombineHiveInputFormat--自动合并小文件
文件大,但列少,文件拆分distribute by rand();
set mapred.reduce.tasks=10;
create table a_1 as
select * from tab_info distribute by rand();
/*
这样会将a表的记录,随机的分散到包含10个文件的a_1表中,再用a_1代替上面sql中的a表,则会用10个map任务去完成。
每个map任务处理大于12M(几百万记录)的数据,效率肯定会好很多。
*/