Hive大白话(●四●)

目录

🧡小表Join大表&大表Join小表(MapJoin)

🧡大表Join大表

空key过滤

空key转换

SMB(Sort Merge Bucket join)

🧡Group By

Count(distinct)去重

🧡行列过滤

列过滤

行过滤

谓词下推

🧡合理设置Map&Reduce数

Map

Reduce

🧡并行执行

🧡严格模式

分区表

order by

笛卡尔积

🧡JVM重用

🧡压缩


💟这里是CS大白话专场,让枯燥的学习变得有趣!

💟没有对象不要怕,我们new一个出来,每天对ta说不尽情话!

💟好记性不如烂键盘,自己总结不如收藏别人!

💌本篇继续总结HIve优化相关知识~

🧡小表Join大表&大表Join小表(MapJoin)

💌当用join连接一个小表和一个大表时,若用MR执行操作则join在Reduce操作阶段,而如果采用MapJoin执行操作则join在Map操作阶段。

💌Mapjoin把小表映射成HashTable,再加载到每个Map的内存中,大表作为Map的输入,直接连接内存中的小表数据。

💌没有Reduce阶段,避免数据倾斜;没有Shuffle阶段,减少IO。

🍠参数设置:

set hive.auto.convert.join = true; //默认为true
set hive.mapjoin.smalltable.filesize = 25000000; //默认25M以下认为是小表

🧡大表Join大表

空key过滤

💌由于空key会发送到同一个Reducer上,当空key(值为NULL)数量太多且为异常数据时,会导致数据倾斜,增加不必要的耗时,因此我们需要在Join之前先对空key进行过滤。

🍠使用场景:非Inner Join,如Left Join;不需要字段为NULL的。

不过滤空key
select a.* from A a left join B b on a.id = b.id;
 
过滤A.id中空key 
select a.* from (select * from A where id is not null) a left join B b on a.id = b.id;

空key转换

💌当空key是非异常数据,需要保留时,可以对其先进行转换,随机赋一个值(不能影响join结果),使空key分散到不同Reducer上。

select a.* from A a full join B b on nvl(a.id,rand()) = b.id;

SMB(Sort Merge Bucket join)

💌对两张表join字段分桶,由于分桶后每个桶内hash值相同,在查询时只需要在对应的桶内查询即可,减少了查询时间。

 🍠参数设置:

set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;

🧡Group By

💌我们知道当同一个key的数据过大时会产生数据倾斜,我们可以在Map端先进行聚合,对查询任务生成两个MR操作:

🍠第一个MR:将相同的Map输出结果拼接一个随机数,随机均匀分布到Reduce中,每个Reduce做部分聚合操作,并输出结果。相同的Group By Key有可能被分发到不同的Reduce中,实现负载均衡。

🍠第二个MR:再根据预处理的数据结果按照Group By Key分布到Reduce中,最后完成最终的聚合操作。相同的Group By Key被分布到同一个Reduce中。

🍠参数设置:

set hive.map.aggr = true; //是否在Map端进行聚合,默认为True
set hive.groupby.mapaggr.checkinterval = 100000; //在Map端进行聚合操作的条目数目
set hive.groupby.skewindata = true; //有数据倾斜的时候进行负载均衡,默认是false

Count(distinct)去重

💌count(distinct)查询只有一个Reducer,会导致整个Job难以完成,在数据量大时,可以将count(distinct)改为group by+count增加Reducer个数,相当于并行去重

set mapreduce.job.reduces = 5;
select count(distinct id) from A;
select count(id) from (select id from A group by id) a;

🧡行列过滤

列过滤

💌尽量使用分区过滤。

行过滤

💌先where过滤,再关联。

select
    a.id
from
    A a
join (select id from A where id <= 10) b
on
    a.id = b.id;

谓词下推

💌保证结果正确的前提下,当join on条件为where过滤条件时(id),谓词(where过滤条件)逻辑会提前执行(Map阶段),减少下游处理的数据量。

🍠参数设置:

set hive.optimize.pdd = true;  //默认为true

🧡合理设置Map&Reduce数

Map

🍠文件大,任务逻辑复杂,可以调小maxSize,让maxSize<blocksize增加Map数,公式如下:

computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M

set mapreduce.input.fileinputformat.split.maxsize=100;

🍠在Map执行前合并小文件,减少Map数:

set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

🍠在MR任务结束时合并小文件:

SET hive.merge.mapfiles = true; //在map-only任务结束时合并小文件,默认true
SET hive.merge.mapredfiles = true; //在MR任务结束时合并小文件,默认false
SET hive.merge.size.per.task = 268435456; //合并文件的大小,默认256M
SET hive.merge.smallfiles.avgsize = 16777216; //当输出文件的平均大小小于该值时,启动一个独立的MR任务进行文件merge

Reduce

🍠计算Reducer数的公式

N = min(hive.exec.reducers.max,总输入数据量/hive.exec.reducers.bytes.per.reducer)

hive.exec.reducers.bytes.per.reducer=256000000;  //每个Reduce处理的数据量默认是256MB
hive.exec.reducers.max=1009;  //每个任务最大的Reduce数,默认为1009

🍠在Hadoop的mapred-default.xml文件中修改,设置每个job的Reduce个数:

set mapreduce.job.reduces = 15;

🧡并行执行

💌在系统资源比较空闲的时候可以开启并行执行,没有依赖关系的Stage可以同时执行。

set hive.exec.parallel=true; //打开任务并行执行
set hive.exec.parallel.thread.number=16;  //同一个sql允许最大并行度,默认为8

🧡严格模式

分区表

💌对于分区表,有时候也会进行全表查询,设置以下参数为true,除非where语句中含有分区字段过滤条件来限制范围,否则不允许执行。

hive.strict.checks.no.partition.filter=true;  //默认false

order by

💌设置以下参数为true,使用了order by语句的查询,要求必须使用limit语句

hive.strict.checks.orderby.no.limit=true;  //默认false

笛卡尔积

💌两个表join时一定要写有效的on条件,设置以下参数为true,不会产生笛卡尔积。

hive.strict.checks.cartesian.product=true;  //默认true

🧡JVM重用

💌设置多个小文件共用一个Java虚拟机。

🧡压缩

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值