Hive优化之笛卡尔积优化(一)

本篇以实例介绍如何优化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来优化,请看下一篇

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容