Hive的多种JOIN优化

案例一:

select
	a.id,a.number,b.number,c.number
from table_tmp a 
join table_tmp b on a.id = b.id 
join table_tmp c on a.id = c.id
where a.business = 'A'
and b.business = 'B'
and c.business = 'C'

如上例中,Hive会对每对join连接对象启动一个MaoReduce任务。首先启动一个MapReduce job对表a和表b进行连接操作,然后再启动一个MapReduce job将第一个MapReudce job的输出和表c进行连接操作。

这里可能有的同学就提出疑问了?为什么不是表b和表c先进行连接操作呢?

因为Hive总是按照从左到右的顺序执行的。

补充:前边的例子中,每个on子句都用到了a.id作为其中一个join连接键。这种情况下,Hive中有个优化:当对3个表或者更多个表进行join连接时,如果每个on子句都使用相同的连接键的话,那么只会产生一个MapReduce job。

案例二(JOIN优化):

select
	a.id,a.number,b.number
from big_table_tmp a 
join small_table_tmp b on a.id = b.id 

表a为大表,表b为小表,我们错误的将小表,放在了后边。

优化:

应该交换下表a和表b的位置,如下:

select
	a.id,a.number,b.number
from small_table_tmp a 
join big_table_tmp b on a.id = b.id 

这样在查询中最后一个表为最大的那个表,在对每行记录进行操作时,它会尝试将其他表缓存起来,然后扫描最后那个表进行计算。因此,我们在编写SQL时需保证查询中表的大小从左到右是依次增加的。同时Hive也提供了一个“标记”机制来显式的告知查询优化器哪张表是大表,使用如下:

select /* STREAMTABLE(a)*/
	a.id,a.number,b.number
from big_table_tmp a 
join small_table_tmp b on a.id = b.id 

这里,Hive通过标记,会将表a 作为驱动表,即使其在查询中不是位于最后面的。

案例三(map-side JOIN): 

 如果所有表中只有一张表是小表,那么可以在最大的表通过mapper的时候将小表完全放到内存中。Hive可以在map端执行连接的过程我们称之为map-side JOIN。这是因为Hive可以和内存中的小表进行逐一匹配,从而省略掉常规连接操作所需要的reduce过程。即使对于很小的数据集,这个优化也明显地要快于常规的连接操作,这样不仅减少了reduce过程,而且有时还可以同时减少map过程的执行步骤。

select /* +MAPJOIN(b)*/
	a.id,a.number,b.number
from big_table_tmp a 
join small_table_tmp b on a.id = b.id 

注意:从Hive v0.7开始,废弃了这种标记的方式,不过如果增加这个标记也是有效的。如果不增加这个标记,用户需要设置属性 hive.auto.convert.join=true,这样Hive才会在必要的时候启动这个优化,默认情况下为false。

set hive.auto.convert.join=true;
select
	a.id,a.number,b.number
from big_table_tmp a 
join small_table_tmp b on a.id = b.id 

 同时需要注意的是,用户也可以配置能够使用这个优化的小表的大小,默认值如下:

hive.mapjoin.smalltable.filesize=25000000

如果用户期望Hive在必要的时候自动启动这个优化的话,也可以将这个(或其他优化配置)设置在${HIVE_HOME}/bin目录下有个.hiverc文件中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值