Hive中的map join、left semi join和sort merge bucket join

map join

map join是将join双方比较小的表直接分发到各个 map进程的内存中,在map进程中进行join操作,这样就不用进行reduce步骤,从而提高了速度。 如果不指定mapjoin或者不符合mapjoin的条件,那么hive解析器会将join操作转换成common join,即在reduce阶段完成join。容易发生数据倾斜。可以用map join把小表全部加载到内存。在map端进行join,避免reducer处理。

left semi join

left semi join(左半连接)用于替代in/exists操作。

--in/exists
select a.id, a.name from a where a.id in (select b.id from b);
select a.id, a.name from a where exists (select id from b where a.id = b.id);

--join(效果等同)
select a.id, a.name from a join b on a.id = b.id;

--left semi join(效果等同)
select a.id, a.name from a left semi join b on a.id = b.id;

select a.id, a.name from a left semi join b on a.id = b.id and b.id > 2;

(1)left semi join子句右边的表只能在ON子句中设置过滤条件,WHERE 子句、SELECT子句或其他地方过滤都不行。
(2)left semi join只传递表的join key给map阶段,因此left semi join最后select的结果只出现左表内容。
(3)因为left semi join是in(keySet)的关系,如果右表是重复记录,左表会跳过,而使用join的话则会一直遍历。这就导致在右表有重复值的情况下left semi join只产生一条数据,join 会产生多条数据,因此left semi join的性能更高。

参考文章有示例图

sort merge bucket join

SMB目的主要是为了解决大表与大表之间的join 问题,分桶即将大表分为小表,然后Map-Side Join解决,分而治之。

对于map端连接的情况,两个表以相同方式划分桶。处理左边表内某个桶的mapper知道右边表内相匹配的行在对应的桶内。因此,mapper只需要获取右表的那个桶的数据即可进行连接 (只是右表存储数据的一小部分)。这一优化方法不要求两个表必须桶的个数相同,两个表桶的个数是倍数关系也可以。

桶中的数据可以根据一个或多个列进行再排序。这样对每个桶的连接就变成了高效的归并排序,可进一步提升map端效率

创建分桶表后开启SMB
set hive.auto.convert.sortmerge.join=true
set hive.optimize.bucketmapjoin=true;
set hive.optimize.bucketmapjoin.sortedmerge=true;

--在join两个分桶表时即可自动使用SMB join。
--从第一个表读取一个存储桶,从第二个表读取相应的存储桶,执行合并排序连接。 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值