`
yugouai
  • 浏览: 491629 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Hive的JOIN用法

 
阅读更多

Hive表连接的语法支持如下:

join_table:
    table_reference JOIN table_factor [join_condition]
  | table_reference {LEFT|RIGHT|FULL} [OUTER] JOIN table_reference join_condition
  | table_reference LEFT SEMI JOIN table_reference join_condition
  | table_reference CROSS JOIN table_reference [join_condition] (as of Hive 0.10)

table_reference:
    table_factor
  | join_table

table_factor:
    tbl_name [alias]
  | table_subquery alias
  | ( table_references )

join_condition:
    ON equality_expression ( AND equality_expression )*

equality_expression:
    expression = expression

 hive只支持等连接,外连接,左半连接。hive不支持非相等的join条件(通过其他方式实现,如left outer join),因为它很难在map/reduce job实现这样的条件。而且,hive可以join两个以上的表。

 

例子

 

写join查询时,有几个典型的点要考虑,如下:

 

等连接

 

只有等连接才允许

SELECT a.* FROM a JOIN b ON (a.id = b.id)
SELECT a.* FROM a JOIN b ON (a.id = b.id AND a.department = b.department)

这两个是合法的连接

 

SELECT a.* FROM a JOIN b ON (a.id <> b.id)

这个是不允许的。

 

多表连接

 

同个查询,可以join两个以上的表

SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2)
 

join的缓存和任务转换

 

hive转换多表join时,如果每个表在join字句中,使用的都是同一个列,只会转换为一个单独的map/reduce。

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被调用。

 

另一方面

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任务,因为b的key1列在第一个join条件使用,而b表的key2列在第二个join条件使用。第一个map/reduce任务join a和b。第二个任务是第一个任务的结果join c。

在join的每个map/reduce阶段,序列中的最后一个表,当其他被缓存时,它会流到reducers。所以,reducers需要缓存join关键字的特定值组成的行,通过组织最大的表出现在序列的最后,有助于减少reducers的内存。

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计算。

类似

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阶段,通过关键字,可以指定哪个表从流接收。

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。

 

join的结果

 

LEFT,RIGHT,FULL OUTER连接存在是为了提供ON语句在没有匹配时的更多控制。例如,这个查询:

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规范。

 

join的过滤

 

Joins发生在where字句前,所以,如果要限制join的输出,需要写在where字句,否则写在JOIN字句。现在讨论的一个混乱的大点,就是分区表

SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key)
WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'

将会连接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结果是不相关的。所以,当外连接时,使用这个语句

SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key AND b.ds='2009-07-07' AND a.ds='2009-07-07'

join的输出会预先过滤,然后你不用对有a.key而没有b.key的行做过滤。RIGHT和FULL join也是一样的逻辑。

 

join的顺序

 

join是不可替换的,连接是从左到右,不管是LEFT或RIGHT join。

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的所有行。

 

为了达到更直观的效果,相反,我们应该从

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 子句或其他地方过滤都不行。

SELECT a.key, a.value FROM a WHERE a.key in (SELECT b.key FROM B);

可以重写为

SELECT a.key, a.val FROM a LEFT SEMI JOIN b on (a.key = b.key)

mapjoin

 

但如果所有被连接的表是小表,join可以被转换为只有一个map任务。查询是

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个桶,下面的连接:

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,这不是默认行为,要使用以下参数:

set hive.optimize.bucketmapjoin = true;

 

如果表在join的列经过排序,分桶,而且他们有相同数量的桶,可以使用排序-合并 join。每个mapper,相关的桶会做连接。如果A和B有4个桶,

SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM A a join B b on a.key = b.key

只能在mapper使用。使用A的桶的mapper,也会遍历B相关的桶。这个不是默认行为,需要配置以下参数:

set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;

 

翻译自 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Joins

分享到:
评论

相关推荐

    使用Hive进行join查询的时报错

    NULL 博文链接:https://weigang-gao.iteye.com/blog/2260663

    Hive Summit 2011-join

    facebook hive中的各种join策略的slides,reporter是个Chinese。

    hive-笔记--hive常用用法

    hive-笔记--hive常用用法: 内部表和外部表,导入数据,导出数据,将数据从hive的表中导出到本地磁盘目录中,HIVE的存储文件格式,修改表的分区,多重插入,HIVE的自定义函数功能,使用explode —— 行转列,配合...

    hive

    hive hive hive hive hive hive hive hive hive hive hive hive

    分布式数据仓库Hive大全

    8. 使用HIVE注意点 43 8.1 字符集 43 8.2 压缩 43 8.3 count(distinct) 43 8.4 JOIN 43 8.5 DML操作 44 8.6 HAVING 44 8.7 子查询 44 8.8 Join中处理null值的语义区别 44 9. 优化与技巧 47 9.1 全排序 47 9.1.1 例1 ...

    Hive用户指南

    8. 使用HIVE注意点 43 8.1 字符集 43 8.2 压缩 43 8.3 count(distinct) 43 8.4 JOIN 43 8.5 DML操作 44 8.6 HAVING 44 8.7 子查询 44 8.8 Join中处理null值的语义区别 44 9. 优化与技巧 47 9.1 全排序 47 9.1.1 例1 ...

    HIVE函数使用方法以及案例介绍.md

    整合HIVE使用方法,含有各种函数操作方法,窗口函数操作方法,并附有案例

    hive sql + left join 数据缺失

    hive sql + left join 数据缺失

    Hive on Spark EXPLAIN statement

    Hive on Spark EXPLAIN statement : 讲述了 Common Join / Map join / Bucket Map Join / Sorted Merge Bucket Map Join / skew join 在explain 中的 树结构 。In Hive, command EXPLAIN can be used to show the ...

    Hive3.1.2编译源码

    使用hive3.1.2和spark3.0.0配置hive on spark的时候,发现官方下载的hive3.1.2和spark3.0.0不兼容,hive3.1.2对应的版本是spark2.3.0,而spark3.0.0对应的hadoop版本是hadoop2.6或hadoop2.7。 所以,如果想要使用高...

    Hive-Summit-2011-join.zip_hive

    Hive: Join Strategies. Facebook summit-2011

    hive-jdbc hive jdbc驱动

    hive-jdbc

    Hive使用手册Hive使用手册

    1 Hive 概念与连接使用: 2 2 Hive支持的数据类型: 2 2.1原子数据类型: 2 2.2复杂数据类型: 2 2.3 Hive类型转换: 3 3 Hive创建/删除数据库 3 3.1创建数据库: 3 3.2 删除数据库: 3 4 Hive 表相关语句 3 4.1 Hive ...

    利用Hive进行复杂用户行为大数据分析及优化案例

    利用Hive进行复杂用户行为大数据分析及优化案例(全套视频+课件...14_Hive中的数据倾斜及解决方案-三种join方式 15_Hive中的数据倾斜及解决方案-group by 16_Hive中使用正则加载数据 17_Hive中使用Python脚本进行预处理

    Hive表生成工具,Hive表生成工具Hive表生成工具

    Hive表生成工具,Hive表生成工具Hive表生成工具

    HIVE函数详解大全

    HIVE函数大全,包括目前HIVE可用的所有函数,里面有详细说明。HIVE是基于Hadoop的一个数据仓库工具,用来进行数据提取、转化、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。

    hive编程指南中文

    《Hive编程指南》是一本Apache Hive的编程指南 旨在介绍如何使用Hive的SQL方法 HiveQL来汇总 查询和分析存储在Hadoop分布式文件系统上的大数据集合 全书通过大量的实例 首先介绍如何在用户环境下安装和配置Hive 并对...

    hive.txt hivesql简单用法脚本代码

    hive hive 简单用法 希望能帮到需要的人,在学习中相互学习

    《Hive数据仓库案例教程》教学课件 第5章 Hive数据操作.pdf

    《Hive数据仓库案例教程》教学课件 第5章 Hive数据操作.pdf《Hive数据仓库案例教程》教学课件 第5章 Hive数据操作.pdf《Hive数据仓库案例教程》教学课件 第5章 Hive数据操作.pdf《Hive数据仓库案例教程》教学课件 第...

    hive练习数据和练习题及答案

    hive练习数据和hive练习题包含了hive练习数据,hive数据的建表ddl和hive练习题,非常适合做hive练习,新手培训,快速...LEFT SEMI JOIN Hive当前没有实现 IN/EXISTS 子查询,可以用 LEFT SEMI JOIN 重写子查询语句。

Global site tag (gtag.js) - Google Analytics