hive中的join

多个表进行join的MapReducer任务的数量

根据最典型的学生课程表,由于学生和课程之间是多对多的关系,所以需要一张中间表stundet_course表进行关联

案例一:查询学生课程信息

select stu.* , c.* from student stu join student_course sc on student.sno = sc.sno join course c on sc.cno = c.cno

大多数情况下,hive会对每一对join连接对象启动一个MapReduce任务,这个例子中就应该是先执行一个mapreducer job 将表student与student_course 表进行连接,输出结果,再执行一个mapreducer job将该输出结果与course表进行连接,输出最终的结果。

案例二:查询学生的住宿地址和家庭地址信息

select stu.* , dorm.* ,home.* from student stu join dorm on student.sno = dorm.sno join home  on stu.sno = home.sno

注意但是在这个例子中,得益于一个优化,因为这边的每一个join的on子句中都使用到了student.sno这个字段,在这种情况下,hive通过一个优化可以在同一个mapreducer中连接3个表
换句话说,当对3个或3个以上的表进行join连接的时候,如果每一个on子句都使用相同的连接键的话,那么只会产生一个mapreduce job。

join连接时表连接的顺序

hive进行连接的时候,会假定最后的一个表是最大的那个表,在对每一行记录进行连接操作的时候,它会先尝试将其他的表缓存起来,然后扫描最后的那张表进行计算,因此用户在连接的时候,需要保证连续查询中的表的大小是从左到右依次增加的。

map-side join

如果连接的表中有一张表是小表,那么完全可以将这张表存放在内存中,直接在map端进行join就可以了(可以在map端将大表与内存中的小表进行逐一匹配),从而省略掉了常规连接操作中所需要的reduce过程。
不过这样做需要进行一些配置:

set hive.auto.convert.join=true

此外还可以设置使用这个优化的小表的大小

#单位bytes
hive.mapjoin.smalltable.filesize=25000000

不过需要注意的是,hive对于右外连接,左外连接不支持这个优化

left semi join

左半开连接:返回左边表的记录,其前提是对于右边表满足on语句中的判定条件,这是一个特殊的inner join

因为hive不支持in关键字,所以只用这个join进行达到这种相同的目的:

案例

得到住在学校的学生的信息

#在mysql中本来是这么写的,但是hive中不支持
select stu.*  from student stu where stu.sno in (select sno from dorm)

#hive中使用优化了的inner joinleft semi join进行操作
select stu.* from student stu left semi join dorm on dorm.sno = stu.sno

注意: 在select和where中不能出现右边表的任何字段。
原理: 对于左边表中的一条记录,在右边一旦找到一条,那么就会立刻停止对右表的扫描,从而效率比inner join要高

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值