HiveSqlSparkSql —— 使用left semi join做in、exists类型子查询优化
LEFT SEMI JOIN(左半连接)介绍
SEMI JOIN
(即等价于LEFT SEMI JOIN
)最主要的使用场景就是解决EXISTS IN
。LEFT SEMI JOIN
(左半连接)是IN/EXISTS
子查询的一种更高效的实现。LEFT SEMI JOIN
虽然含有LEFT
,但其实现效果等价于INNER JOIN
,但是JOIN
结果只取原左表中的列。
优化实例
实例表准备:
CREATE TABLE test.user1(`id` bigint
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS textfile
LOCATION '/big-data/test/user1';CREATE TABLE test.user2(`id` bigint,`role` string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS textfile
LOCATION '/big-data/test/user2';
实例数据准备:
insert into test.user1 values(-1);
insert into test.user1 values(1);insert into test.user2 values(-1,'C1');
insert into test.user2 values(1,'C1');
insert into test.user2 values(1,'C2');
数据测试:
JOIN
--join的select的结果中可以有t1(左表),t2(右表)两张表的字段
SELECT t1.id,t2.role
FROM test.user1 t1
JOIN test.user2 t2
ON t1.id=t2.id;
结果:
left semi join
--left semi join的select的结果中只允许出现t1(左表)表的字段
SELECT t1.id
FROM test.user1 t1
LEFT SEMI JOIN test.user2 t2
ON t1.id=t2.id;--等价于
SELECT t1.id
FROM test.user1 t1
WHERE id IN (SELECTid FROM test.user2);--等价于
SELECT t1.id
FROM test.user1 t1
WHERE EXISTS (SELECT 1 FROM test.user2 t2WHERE t1.id=t2.id);
结果:
异常:
这样如果结果涉及查询右表中的字段就会报错写会报错:
SELECT t1.id,t2.role
FROM test.user1 t1
LEFT SEMI JOIN test.user2 t2
ON t1.id=t2.id;
结果:
join on与left semi join的联系
他们都是
hive join
方式的一种,join on
属于common join(shuffle join/reduce join)
,而left semi join
则属于map join(broadcast join)
的一种变体,从名字可以看出他们的实现原理有差异。
join on与left semi join的区别
(1)
Left Semi Join
,也叫半连接
,是从分布式数据库中借鉴过来的方法。它的产生动机是:对于reduce side join,跨机器的数据传输量非常大,这成了join操作的一个瓶颈,如果能够在map端过滤掉不会参加join操作的数据,则可以大大节省网络IO,提升执行效率
。
实现方法: 选取一个小表,假设是File1
,将其参与join
的key
抽取出来,保存到文件File3
中,File3
文件一般很小,可以放到内存中。在map
阶段,使用DistributedCache
将File3
复制到各个TaskTracker
上,然后将File2
中不在File3
中的key
对应的记录过滤掉,剩下的reduce
阶段的工作与reduce side join
相同。
left semi join
是只传递表的join key
给map
阶段 , 如果key
足够小还是执行map join
, 如果不是则还是common join
。关于common join(shuffle join/reduce join)
的原理请参考文末refer
。
(2)left semi join
子句中右边的表只能在ON
子句中设置过滤条件,在WHERE
子句、SELECT
子句或其他地方
过滤都不行。
(3)对待右表中重复key
的处理方式差异:因为 left semi join 是 in(keySet) 的关系,遇到右表重复记录,左表会跳过,而 join on 则会一直遍历
。left semi join
中最后的结果是这会造成性能,以及join
结果上的差异。
(4)left semi join中最后 select 的结果只许出现左表,因为右表只有join key参与关联计算了,而 join on 默认是整个关系模型都参与计算了
。
这里借鉴网上一个实例图在解释下:
比如以下A
表和B
表进行join
或 left semi join
,然后 select
出所有字段,结果区别如下:(蓝色叉的那一列实际是不存在left semi join
中的,因为最后 select
的结果只许出现左表。)
写在最后
对于大多数情况下 JOIN ON
和left semi on
是对等的,在右表存在重复数据记录时,导致结果差异,所以大家在使用的时候最好能了解这两种方式的原理,是否和我们想要的数据效果一致。
HiveSqlSparkSql —— 使用left semi join做in、exists类型子查询优化相关推荐
- 【Hive】left semi join(exists、in)和 left join 区别
left semi join(exists.in)和 left join 区别 left semi join 基本认识 对比 执行计划 小结 left semi join 基本认识 LEFT SEMI ...
- Hive 实现 IN 和 NOT IN 子句 和 LEFT SEMI JOIN 应用
目前hive不支持 in或not in 中包含查询子句的语法,所以只能通过left join实现. 假设有一个用户浏览商品表skim,和一个用户购买商品表buy.如下 skim表 userId ite ...
- Hive in、exists 和 left semi join
with query1 as (select stack(4, 'A', 1, 'B', 2, 'C', 3, 'D', 4) as (k,v) ), query2 as (select stack( ...
- Hive中的in、exists和left semi join
在hive sql开发的过程中,对于当前数据在另一个数据集合中,是否存在的判断有三种方式,一种是in ,一种是exists,另一种可以是left semi join,但是由于hive不支持in|not ...
- mysql semi join_MySQL 通过semi join 优化子查询
半连接是MySQL 5.6.5引入的,多在子查询exists中使用,对外部row source的每个键值,查找到内部row source匹配的第一个键值后就返回,如果找到就不用再查找内部row sou ...
- 面试官:说说left join和left semi join 两者有什么区别?
张工是一名程序员,主要是做java开发,有次到一家软件公司面试软件开发岗位,面试官问了他两个问题,其中有一个问题是这样的这样: 说说left join和left semi join 有什么区别? 对于 ...
- exist优化 in mysql_MySQL 子查询优化[IN/EXISTS]--smei join
MySQL 里面有哪些子查询呢? 标量子查询 内联视图 半连接/反连接 本篇主要讲解半连接查询 半连接?可以这么理解 where 条件后面有In/EXISTS这样的子查询称为semi jion 格式: ...
- oracle+semijoin,Semi join 与anti join
1.semi join Oracle在处理exists或in的时候,会使用semi join的连接方式: sys@EBANK>select object_name,object_type fro ...
- join left semi_Hive的left join、left outer join和left semi join三者的区别
Hive的Join的文档说明地址: https://cwiki.apache.org/confluence/display/Hive/LanguageManual%2BJoins 以下为两个测试数据表 ...
最新文章
- 六月开发语言排行榜出炉 ActionScript回前20
- python寻找相似用户_Python 寻找相近的用户
- Java并发编程-volatile关键字介绍
- java开发利器 源码_Java开发的利器: 反编译工具 JD-GUI
- 20165307《网络对抗技术》Exp1 PC平台逆向破解
- 动态规划——看似dp的贪心问题最大乘积(蓝桥杯试题集)
- android studio 新建工程慢,关于AndroidStudio新建与编译项目速度慢解决办法
- 打印机驱动 - HP LaserJet P1008(适用于大部分惠普打印机)
- coap协议开发实例C语言,CoAP协议及开源实现
- python计算相关性显著性p值_基于python如何实现计算两组数据P值
- JavaScript编程精解(笔记1)
- PV-RCNN: Point-Voxel Feature Set Abstraction for 3D Object Detection阅读
- docker 自动签到模板制作
- js判断设备是ios还是安卓,以及微信端
- C语言字母an,易错题之大一C语言英语
- 全屏css,CSS之全屏背景图
- try(){}的简单理解
- 游戏后台搭建(基于cocoscreator+nodejs+linux-阿里云)
- 图纸打印什么时候用蓝图_cad图怎么打印成施工蓝图
- Stata新命令:readWind-快速读入并转换万德数据
热门文章
- 令人匪夷所思的 Magic 之魔数,你真的不会
- 【数据挖掘】主成分分析Python实现
- php 如何实现心跳包,Socket心跳机制-JS+PHP实现
- type-c英文怎么读音发音,type-c怎么读英语发音
- 教你如何用Python部署QQ频道机器人
- 微型计算机百度云,STONE_百度云资源_盘多多如风搜_盘搜搜_哎哟喂啊
- java毕业设计木材产销系统的生产管理模块mybatis+源码+调试部署+系统+数据库+lw
- 带你掌握最常用的数据分析图表
- 【c++数据结构】栈混洗的甄别算法
- 如何在以太坊上发行自己的代币