Hive优化之Mapjoin

一、场景

MapJoin是Hive的一种优化操作,其适用于小表JOIN大表的场景,由于表的JOIN操作是在Map端且在内存进行的,所以其并不需要启动Reduce任务也就不需要经过shuffle阶段,从而能在一定程度上节省资源提高JOIN效率。

二、使用

2.1 Hive v0.7 之前通过在查询语句中增加一个标记进行触发:
SELECT /*+ MAPJOIN(smalltable)*/  smalltable.key,smalltable.value
FROM smalltable JOIN bigtable ON smalltable.key = bigtable.key
2.2 从Hive v0.7版本开始,废弃了2.1中的方式,但是如果增加了这个标记同样是有效的,如果不加这个标记,需要设置

set hive.auto.convert.JOIN=true;

这样hive才会在必要的时候启动这个优化,该参数默认情况下为fasle。我们也可以配置能够使用这个优化的小表的大小,参数(单位是字节,默认25M):

set hive.mapjoin.smalltable.filesize=25000000;

注意: 
使用默认启动该优化的方式如果出现默名奇妙的BUG(比如MAPJOIN并不起作用),就将以下两个属性置为fase手动使用
MAPJOIN标记来启动该优化
set hive.auto.convert.join=false(关闭自动MAPJOIN转换操作)
set hive.ignore.mapjoin.hint=false(不忽略MAPJOIN标记)
2.3 Mapjoin还有一个比较重要的用处就是支持不等连接的join操作

如果将不等条件放在where中,则join阶段通常是通过on 1=1 这种会产生笛卡尔积的方式,效率比较低,如果采用mapjoin的方式,则会在map的过程中完成不等值的join操作,例如:

    set hive.auto.convert.join=true;
    
    select   smalltable.key,
             smalltable.value 
    from smalltable
    join bigtable on smalltable.value>bigtable.value;
2.4 Mapjoin其他参数
2.4.1 多Mapjoin合并

hive.auto.convert.join.noconditionaltask 是否将多个mapjoin合并为一个
hive.auto.convert.join.noconditionaltask.size : 多个mapjoin转换为1个时,所有小表的文件大小总和的最大值。

eg:
一个大表顺序关联3个小表a(10M), b(8M),c(12M),如果hive.auto.convert.join.noconditionaltask.size的值:
a. 小于18M,则无法合并mapjoin,必须执行3个mapjoin;
b. 大于18M小于30M,则可以合并a和b表的mapjoin,所以只需要执行2个mapjoin;
c. 大于30M,则可以将3个mapjoin都合并为1个。

合并mapjoin的好处:
因为每个mapjoin都要执行一次map,需要读写一次大表的数据,所以多个mapjoin就要做多次的数据读写,合并mapjoin后只用读写一次,自然能大大加快速度。但是执行map是内存大小是有限制的,在一次map里对多个小表做mapjoin就必须把多个小表都加入内存,为了防止内存溢出,所以加了hive.auto.convert.join.noconditionaltask.size参数来做限制。不过,这个值只是限制输入的表文件的大小,并不代表实际mapjoin时hashtable的大小。

2.4.2 LocalTask内存使用率

hive.mapjoin.localtask.max.memory.usage 将小表转成hashtable的本地任务的最大内存使用率,默认0.9默认值是0.9

在mapjoin任务执行前,会创建一个新的本地的MapReduce任务,这个新任务负责将小表数据从 HDFS 上读取到内存中的哈希表中。读完后,将内存中的哈希表序列化为哈希表文件。在下一阶段,当 MapReduce 任务启动时,会将这个哈希表文件上传到 Hadoop 分布式缓存中,该缓存会将这些文件发送到每个 Mapper 的本地磁盘上。
在这个过程中,查询处理器在一个子的jvm里运行这个本地MapReduction任务,jvm堆大小跟Mapper的堆大小一样。本地MR可能内存消耗殆尽,查询处理器精确的计算本地MR的内存大小,一旦内存超过了设定的值,那么这个MR就会自动kill掉。可以通过设置上面这个参数尽可能多的使用Map的堆内存。

2.4.3 其他

hive.mapjoin.followby.gby.localtask.max.memory.usage : 如果mapjoin后面紧跟着一个group by任务,这种情况下 本地任务的最大内存使用率,默认是0.55。
hive.mapjoin.check.memory.rows : localtask每处理完多少行,就执行内存检查。默认为100000
如果我们的localtask的内存使用超过阀值,任务会直接失败。

三、说明

Mapjoin不支持右外连接(right outer join)和全外连接(full outer join),支持内连接(inner join)和左外连接(left outer join)

四、参考

Mapjoin原理
Hive MapJoin(小表对大表)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值