Hive系列-in与left semi join

更多文章参考微信公众号:小满锅

select s_id from score where c_id in(
select c_id from score where s_id='01')
group by s_id;

select b.s_id
from score b join score c on b.c_id=c.c_id and c.s_id='01' group by b.s_id;


select s_id
from score b left semi join score c on b.c_id=c.c_id and c.s_id='01' group by s_id;

先看看三个SQL,在说这个SQL之前,我们有几个表:
学生表:s_id,s_name,s_birth,s_sex
分数表:s_id,c_id,s_core
其他表暂时不管
上面的SQL应该就是说要找到至少有一门课程和01同学所学课程相同的同学


先来看看第一条SQL

select s_id from score where c_id in(
select c_id from score where s_id='01')
group by s_id;

这里显示一个子查询,将01同学的c_id筛选出来了,然后形成一个子集吧,最后外查询将选修的课程给筛选出来,然后再根据s_id分组,选出学生id。实际上这个group by就是一个去重嘛对吧
使用explain看一下查询计划👌
在这里插入图片描述
最里面黄色框框是两个map,即分别取扫描两个表,而红色框框就是两个表进行了一个mapjoin,而蓝色框框Reduce就是根据mapjoin的结果对key分组,可以看到这个过程发生了Shuffle,最后白色框框也是Reduce,应该是将结果汇总吧。


select b.s_id
from score b join score c on b.c_id=c.c_id and c.s_id='01' group by b.s_id;

查看一下执行计划
在这里插入图片描述
两者结果是一样,这是执行计划不同,但是为什么前面那个会多个Reduce呢。


select s_id
from score b left semi join score c on b.c_id=c.c_id and c.s_id='01' group by s_id;

前面那个用的是left join,看起来和这个差不多,但是性能还是有细微的区别的,前面的优化只是做了一个map join,但是呢,那个map join只是将小表复制到多个maptask了。而这个就是只将右表中符号条件的数据key去出来而已,所以不用去除所有,而且对于那些parquet的存储格式的数据,可以跳过一大批。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小满锅lock

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值