Hive 基本语法操练(五):Hive 的 JOIN 用法
Hive 的 JOIN 用法
hive只支持等连接,外连接,左半连接。hive不支持非相等的join条件(通过其他方式实现,如left outer join),因为它很难在map/reduce中实现这样的条件。而且,hive可以join两个以上的表。
1、等连接
只有等连接才允许
hive> SELECT a.* FROM a JOIN b ON (a.id = b.id);
hive> SELECT a.* FROM a JOIN b ON (a.id = b.id AND a.department = b.department);
2、多表连接
同个查询,可以join两个以上的表
hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2);
3、join的缓存和任务转换
hive转换多表join时,如果每个表在join字句中,使用的都是同一个列,只会转换为一个单独的map/reduce。
hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1);
被转换为两个map/reduce任务,因为b的key1列在第一个join条件使用,而b表的key2列在第二个join条件使用。第一个map/reduce任务join a和b。第二个任务是第一个任务的结果join c。
hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2);
在join的每个map/reduce阶段,序列中的最后一个表,当其他被缓存时,它会流到reducers。所以,reducers需要缓存join关键字的特定值组成的行,通过组织最大的表出现在序列的最后,有助于减少reducers的内存。
hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1);
三个表,在同一个独立的map/reduce任务做join。a和b的key对应的特定值组成的行,会缓存在reducers的内存。然后reducers接受c的每一行,和缓存的每一行做join计算。
hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2);
这里有两个map/reduce任务在join计算被调用。第一个是a和b做join,然后reducers缓存a的值,另一边,从流接收b的值。第二个阶段,reducers缓存第一个join的结果,另一边从流接收c的值。
在join的每个map/reduce阶段,通过关键字,可以指定哪个表从流接收。
hive> SELECT /*+ STREAMTABLE(a) */ a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1);
三个表的连接,会转换为一个map/reduce任务,reducer会把b和c的key的特定值缓存在内存里,然后从流接收a的每一行,和缓存的行做join。
4、join的结果
LEFT,RIGHT,FULL OUTER连接存在是为了提供ON语句在没有匹配时的更多控制。例如,这个查询:
hive> SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key);
将会返回a的每一行。如果b.key等于a.key,输出将是a.val,b.val,如果a没有和b.key匹配,输出的行将是 a.val,NULL。如果b的行没有和a.key匹配上,将被抛弃。语法"FROM a LEFT OUTER JOIN b"必须写在一行,为了理解它如何工作——这个查询,a是b的左边,a的所有行会被保持;RIGHT OUTER JOIN将保持b的所有行, FULL OUTER JOIN将会保存a和b的所有行。OUTER JOIN语义应该符合标准的SQL规范。
5、join的过滤
Joins发生在where字句前,所以,如果要限制join的输出,需要写在where字句,否则写在JOIN字句。现在讨论的一个混乱的大点,就是分区表
hive> SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key) WHERE a.ds='2018-05-22' AND b.ds='2018-05-22';
将会连接a和b,产生a.val和b.val的列表。WHERE字句,也可以引用join的输出列,然后过滤他们。 但是,无论何时JOIN的行找到a的key,但是找不到b的key时,b的所有列会置成NULL,包括ds列。这就是说,将过滤join输出的所有行,包括没有合法的b.key的行。然后你会在LEFT OUTER的要求扑空。 也就是说,如果你在WHERE字句引用b的任何列,LEFT OUTER的部分join结果是不相关的。所以,当外连接时,使用这个语句
hive> SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key AND b.ds='2018-05-22' AND a.ds='2018-05-22';
join的输出会预先过滤,然后你不用对有a.key而没有b.key的行做过滤。RIGHT和FULL join也是一样的逻辑。
6、join的顺序
join是不可替换的,连接是从左到右,不管是LEFT或RIGHT join。
hive> SELECT a.val1, a.val2, b.val, c.val FROM a JOIN b ON (a.key = b.key) LEFT OUTER JOIN c ON (a.key = c.key);
首先,连接a和b,扔掉a和b中没有匹配的key的行。结果表再连接c。这提供了直观的结果,如果有一个键都存在于A和C,但不是B:完整行(包括 a.val1,a.val2,a.key)会在"a jOIN b"步骤,被丢弃,因为它不在b中。结果没有a.key,所以当它和c做LEFT OUTER JOIN,c.val也无法做到,因为没有c.key匹配a.key(因为a的行都被移除了)。类似的,RIGHT OUTER JOIN(替换为LEFT),我们最终会更怪的效果,NULL, NULL, NULL, c.val。因为尽管指定了join key是a.key=c.key,我们已经在第一个JOIN丢弃了不匹配的a的所有行。
为了达到更直观的效果,相反,我们应该从
hive> FROM c LEFT OUTER JOIN a ON (c.key = a.key) LEFT OUTER JOIN b ON (c.key = b.key);
LEFT SEMI JOIN实现了相关的IN / EXISTS的子查询语义的有效途径。由于Hive目前不支持IN / EXISTS的子查询,所以你可以用 LEFT SEMI JOIN 重写你的子查询语句。LEFT SEMI JOIN 的限制是, JOIN 子句中右边的表只能在 ON 子句中设置过滤条件,在 WHERE 子句、SELECT 子句或其他地方过滤都不行。
hive> SELECT a.key, a.value FROM a WHERE a.key in (SELECT b.key FROM B);
可以重写为
hive> SELECT a.key, a.val FROM a LEFT SEMI JOIN b on (a.key = b.key);
7、map 端 join
但如果所有被连接的表是小表,join可以被转换为只有一个map任务。查询是
hive> SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM a join b on a.key = b.key;
不需要reducer。对于每一个mapper,A和B已经被完全读出。限制是a FULL/RIGHT OUTER JOIN b不能使用。
如果表在join的列已经分桶了,其中一张表的桶的数量,是另一个表的桶的数量的整倍,那么两者可以做桶的连接。如果A有4个桶,表B有4个桶,下面的连接:
hive> SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM a join b on a.key = b.key;
只能在mapper工作。为了为A的每个mapper完整抽取B。对于上面的查询,mapper处理A的桶1,只会抽取B的桶1,这不是默认行为,要使用以下参数:
hive> set hive.optimize.bucketmapjoin = true;
如果表在join的列经过排序,分桶,而且他们有相同数量的桶,可以使用排序-合并 join。每个mapper,相关的桶会做连接。如果A和B有4个桶
hive> SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM A a join B b on a.key = b.key;
只能在mapper使用。使用A的桶的mapper,也会遍历B相关的桶。这个不是默认行为,需要配置以下参数:
hive> set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
hive> set hive.optimize.bucketmapjoin = true;
hive> set hive.optimize.bucketmapjoin.sortedmerge = true;
以上就是博主为大家介绍的这一板块的主要内容,这都是博主自己的学习过程,希望能给大家带来一定的指导作用,有用的还望大家点个支持,如果对你没用也望包涵,有错误烦请指出。如有期待可关注博主以第一时间获取更新哦,谢谢!
版权声明:本文为博主原创文章,未经博主允许不得转载。
Hive 基本语法操练(五):Hive 的 JOIN 用法的更多相关文章
- Hive基本语法操练
建表规则如下: CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COMMENT col_comment ...
- Hive 基本语法操练(六):Hive 的权限控制
Hive 的权限控制 Hive从0.10可以通过元数据控制权限.但是Hive的权限控制并不是完全安全的.基本的授权方案的目的是防止用户不小心做了不合适的事情. 为了使用Hive的授权机制,有两个参数必 ...
- Hive 基本语法操练(二):视图和索引操作
1. 视图操作 ------- 1) 创建一个测试表. ``` hive> create table test(id int,name string); OK Time taken: 0.385 ...
- Hive 基本语法操练(一):表操作
Hive 和 Mysql 的表操作语句类似,如果熟悉 Mysql,学习Hive 的表操作就非常容易了,下面对 Hive 的表操作进行深入讲解. **(1)先来创建一个表名为student的内部表** ...
- Hive 基本语法操练(三):分区操作和桶操作
(一)分区操作 Hive 的分区通过在创建表时启动 PARTITION BY 实现,用来分区的维度并不是实际数据的某一列,具体分区的标志是由插入内容时给定的.当要查询某一分区的内容时可以采用 WHER ...
- Hive 基本语法操练(四):Hive 复合类型
hive语法中主要提供了以下复合数据类型: 1)Structs: structs内部的数据可以通过DOT(.)来存取.例如,表中一列c的类型为STRUCT{a INT; b INT},我们可以通过c. ...
- Hadoop Hive sql语法详解
Hadoop Hive sql语法详解 Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件 ...
- 深入浅出Hive企业级架构优化、Hive Sql优化、压缩和分布式缓存(企业Hadoop应用核心产品)
一.本课程是怎么样的一门课程(全面介绍) 1.1.课程的背景 作为企业Hadoop应用的核心产品,Hive承载着FaceBook.淘宝等大佬 95%以上的离线统计,很多企业里的离线统 ...
- Hive 文件格式 & Hive操作(外部表、内部表、区、桶、视图、索引、join用法、内置操作符与函数、复合类型、用户自定义函数UDF、查询优化和权限控制)
本博文的主要内容如下: Hive文件存储格式 Hive 操作之表操作:创建外.内部表 Hive操作之表操作:表查询 Hive操作之表操作:数据加载 Hive操作之表操作:插入单表.插入多表 Hive语 ...
随机推荐
- VisualGDB系列4:概述-Linux程序与VS
根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 本文将会阐述如何使用VisualGDB来 ...
- 怎么查看mysql的安装目录,环境:windows+mysql+navicat
怎么查看mysql的安装目录 如果忘记了MySQL的安装目录,怎么快速找到呢?方法或许很多,作者觉得这种最方便了 环境:windows+mysql+navicat 方法:进入mysql命令行输入:sh ...
- c语言基础 c和指针
句子 c规定数组名代表数组首元素的地址 如果&a 则代表整个数组 没有内存哪来的指针 数据类型的本质:固定大小内存的别名 变量的本质:(一段连续)内存空间的别名,内存空间的标号 指针是一种数据 ...
- 高级查询子条件查询filter
Filter Context 在查询过程中,只判断该文档是否满足条件,只有Yes或者No { "query":{ "bool":{ //布尔关键词 " ...
- Hive中SELECT TOP N的方法(order by与sort by的区别)
我想说的SELECT TOP N是取最大前N条或者最小前N条. Hive提供了limit关键字,再配合order by可以很容易地实现SELECT TOP N. 但是在Hive中order by只能使 ...
- win7中配置eclipse连接Ubuntu内的hadoop
Hadoop java 分布式 云计算 数据库 目录[-] 1.设置Ubuntu静态IP: 1)配置网卡参数到interfaces文件: 2)重启网卡: 2.配置Ubuntu的hosts: 3.配置V ...
- Luogu 4768 [NOI2018]归程
并不会写Kruskal重构树,两个$log$跑得比较卡. 首先考虑一下没有强制在线的要求怎么办,有一个比较容易想到的做法就是先跑一遍最短路,然后把所有边按照海拔从大到小排序,把所有询问的海拔也从大到小 ...
- URAL 2019 Pair: normal and paranormal (STL栈)
题意:在一个半圆内,有2*n个点,其中有大写字母和小写字母.其中你需要连接大写字母到小写字母,其中需要保证这些连接的线段之间没有相交. 如果能够实现,将大写字母对应的小写字母的序号按序输出. 析:我把 ...
- From COM to COM 侯捷 1998.06.12
摘要: 本文簡介 C++ Object Model 和 Component Object Model 的基本概念,並引介四本書籍: 1. Inside The C++ Object Model 2. ...
- MVC下使用日期控件
初学MVC,使用日期控件的时候发现不是特别理想,本来是想直接使用JQuery的日期控件的,发现支持的不是很好,type类型要改成date才能使用,而且编辑的时候使用@Html.EditFor也不能绑定 ...