本篇以实例介绍如何优化Hive大表关联小表笛卡尔积如何优化
优化:1.分析代码 2.查看数据
set hive.mapred.mode=nonstrict;
create table dw_db_temp.aBigCartesianJoinSmall as
select a.cal_dt,b.user_mobile
from aSmallTable a
join aBigTable b
where a.cal_dt<=b.last_update and a.cal_dt<='2018-10-24' anda.cal_dt>='2018-04-01'
group by a.cal_dt,b.user_mobile;
1)没有关联条件,笛卡尔积关联;2)关联表一大一小。
大表Join小表普通笛卡尔积使用Map Join
打开参数:set hive.auto.convert.join=true再跑一次
只有一个map 一个reduce 毫无并发,desc查看大表信息,大表只有两个字段,数据条数多,但只有一个hdfs block
set mapreduce.job.reduces=25; //调整reduce个数
SET hive.merge.mapfiles=true //开启Map-only任务结束后的小文件合并
SET hive.merge.mapredfiles=true //开启Map-Reduce任务结束后的小文件合并(默认false)
SET hive.merge.size.per.task=256000000 //控制每个任务合并小文件后的文件大小(默认256M)
SET hive.merge.smallfiles.avgsize=150000000 //告诉hadoop什么样的文件属于小文件(默认16M)
drop table if exists hdp_anjuke_dw_stage.xujie_test_01;
create table hdp_anjuke_dw_stage.xujie_test_01 as
select * from hdp_anjuke_dw_db_temp.nan_soufang_grab_broker_gather_01 a
distribute by rand(123);
说明:此处我们通过创建一个新的临时表,把源表记录数随机打散到25个输出文件中,这样下一个阶段的输入Map数会有25个,同时关闭小文件合并相关等参数。
SET mapreduce.input.fileinputformat.split.maxsize=256000000; //每个split最大值
SET mapreduce.input.fileinputformat.split.minsize.per.node=256000000; //一个节点上split的最小值 ,多个节点文件是否需要合并
SET mapreduce.input.fileinputformat.split.minsize.per.rack=256000000; //一个交换机下split的最小值,多个交换机文件是否需要合并
SET hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; //执行Map前进行小文件合并
完整代码如下
--重分发数据到25个输出文件,并关闭小文件合并,为下一个阶段调整Map输入做准备
set mapreduce.job.reduces=25;
set hive.merge.mapredfiles=false;
create table table1 as
select cast(1 as int) as join_key,a.*
from aBigTable a
distribute by rand(123);
--调整inputSplit切割、合并文件大小的阈值,使其适配文件个数,并打开MapJoin优化,同时增大并发能力
set hive.auto.convert.join=true;
set mapreduce.job.reduces=22;
SET mapreduce.input.fileinputformat.split.maxsize=10000000;
SET mapreduce.input.fileinputformat.split.minsize.per.node=10000000;
SET mapreduce.input.fileinputformat.split.minsize.per.rack=10000000;
create table dw_db_temp.aBigCartesianJoinSmall as
select b.cal_dt,a.user_mobile
from aSmallTable a
join table1 b on (a.join_key = b.join_key)
where a.last_update>=b.cal_dt
group by b.cal_dt,user_mobile;
这是大表Join小表的情况,可以将小表广播来Mapjoin,如果是大表Join大表呢?
如果是没有关联条件的大笛卡尔积,是没法做优化的,如果是N:N join的小笛卡尔积,Hive有SMB Join来优化,请看下一篇