1.排序的选择
尽量不要用order by 进行全局排序
2.合理使用笛卡尔积
尽量不要使用笛卡尔积,数据量会很大,笛卡尔积是A表的每条数据关联B表的每条数据。
使用笛卡尔积时一定要加上过滤条件,减少数据的输入。
3.in, exists, not in的高效实现
in可以用left semi join 实现,也可以用left join where is not null
select * from a where id in (select id from b);
select a.* from a left semi join b on a.id=b.id;
select a.* from a left join b on a.id=b.id where b.id is not null;
not in 可以用 left join where is null
select a.* from a left outer join b on a.id=b.id where b.id is null;
4.hive合并小文件的配置项
1.输入合并,对map的输入小文件进行逻辑切片合并,防止每个小文件开启一个逻辑切片
set mapred.min.split.size.per.node=100000000; #一个节点上split的至少的大小
set mapred.min.split.size.per.rack=100000000; #一个交换机下split的至少的大小
2.输出合并,MR作业结束后,判断生成文件的平均大小,如果小于阀值,就再启动一个job来合并文件
set hive.merge.mapfiles = true #在Map-only的任务结束时合并小文件
set hive.merge.mapredfiles = true #在Map-Reduce的任务结束时合并小文件
set hive.merge.size.per.task = 256*1000*1000 #合并文件的大小
set hive.merge.smallfiles.avgsize=16000000 #当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
3.执行Map前进行小文件合并
set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
5.开启jvm重用
设置多个,一个jvm中运行多个任务,减少了每一个任务执行的时候 容器的启动和销毁的时间
set mapred.job.reuse.jvm.num.tasks=3;
6.开启map输出数据聚合,相当于combiner
set hive.map.aggr = true; ---开启map端聚合
7.开启mapjoin
set hive.auto.convert.join = true;
set hive.mapjoin.smalltable.filesize =25000000; 25M
select /*+ mapjoin(t2,t3,t4) */
,t1.ssoid
,t1.model
,t1.os_version
,t1.rom_version
,t1.android_version
from
(
select *
from ${dbname_source}.dwd_theme_general_function_inc_h
where dayno=${v_day}
and ${expired_imei_check}
)t1
left outer join
(
select imei,openid as duid
from ${brand_name}_os_dw.${mapping_table_d}
where dayno=${v_day}
and open_type = 1
)t2 on t1.duid = t2.duid
left outer join
(
select imei,openid as ouid
from ${brand_name}_os_dw.${mapping_table_d}
where dayno=${v_day}
and open_type = 2
)t3 on t1.ouid = t3.ouid
left outer join
(
select imei,openid as guid
from ${brand_name}_os_dw.${mapping_table_d}
where dayno=${v_day}
and open_type = 3
)t4 on t1.guid = t4.guid
8.开启group by的数据倾斜优化
set