设为首页 加入收藏

TOP

HiveJoin(一)
2015-11-21 01:41:42 来源: 作者: 【 】 浏览:4
Tags:HiveJoin

LanguageManualJoins

Join Syntax

Hive支持下面的表join语法结构:

join_table:

table_reference JOIN table_factor[join_condition]

| table_reference {LEFT|RIGHT|FULL} [OUTER]JOIN table_reference join_condition

| table_reference LEFT SEMI JOINtable_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 ( ANDequality_expression )*

?

equality_expression:

expression = expression

注释:在Hive的joins,outerjoins和left semi joins只支持等式连接,不支持不等式连接,因为不等式连接很难转化成map/reduce的job。

?

Version 0.13.0+: Implicit joinnotation(隐式连接符号)

从Hive0.13.0开始支持Implicit join notation,允许from子句去join以逗号分隔的表,省略掉join关键字,如下:

SELECT *
FROM table1t1, table2 t2, table3 t3
WHERE t1.id= t2.id AND t2.id = t3.id AND t1.zipcode = '02535';

?

Version 0.13.0+: Unqualified columnreferences

从Hive0.13.0开始支持非指定字段的引用,如下:

CREATE TABLE a (k1 string, v1 string);
CREATE TABLE b (k2 string, v2 string);

SELECT k1, v1, k2, v2
FROM a JOIN b ON k1 = k2;

如果一个字段在多个表中出现,则Hive会指出它是一个歧义的引用。

Examples

下面有几点关于Hive的join连接重要的地方:

1) 只支持等式join

SELECTa.* FROM a JOIN b ON (a.id = b.id);

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

2) 支持多张表join

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

3) 生成一个MRJob:多表连接,如果多个表中每个表都使用同一个列进行连接(出现在JOIN子句中),则只会生成一个MR(map/reduce)Job比如:

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

三个表a、b、c都分别使用了同一个字段进行连接,亦即同一个字段同时出现在两个JOIN子句中,从而只生成一个MRJob。

生成多个MRJob:多表连接,如果多表中,其中存在一个表使用了至少2个字段进行连接(同一个表的至少2个列出现在JOIN子句中),则会至少生成2个MRJob,如下的sql将转化为两个map/reduce任务:

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

三个表基于2个字段进行连接,这两个字段b.key1和b.key2同时出现在b表中。连接的过程是这样的:首先a和b表基于a.key和b.key1进行连接,对应着第一个MRJob;表a和b连接的结果,再和c进行连接,对应着第二个MRJob。

4) 表连接顺序优化

多表连接,会转换成多个MRJob,每一个MR Job在Hive中称为JOIN阶段(Stage)。在每一个Stage,按照JOIN顺序中的最后一个表应该尽量是大表,因为JOIN前一阶段生成的数据会存在于Reducer的buffer中,通过stream最后面的表,直接从Reducer的buffer中读取已经缓冲的中间结果数据(这个中间结果数据可能是JOIN顺序中,前面表连接的结果的Key,数据量相对较小,内存开销就小),这样,与后面的大表进行连接时,只需要从buffer中读取缓存的Key,与大表中的指定Key进行连接,速度会更快,也可能避免内存缓冲区溢出。例如:

SELECTa.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key =b.key1);

这个JOIN语句,会生成一个MRJob,在选择JOIN顺序的时候,数据量相比应该是b< c,表a和b基于a.key= b.key1进行连接,得到的结果(基于a和b进行连接的Key)会在Reducer上缓存在buffer中,在与c进行连接时,从buffer中读取Key(a.key=b.key1)来与表c的c.key进行连接。
另外,也可以通过给出一些Hint信息来启发JOIN操作,这指定了将哪个表作为大表,从而得到优化。例如:

SELECT/*+ STREAMTABLE(a) */ a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOINc ON (c.key = b.key1);

上述JOIN语句中,a表被视为大表,则首先会对表b和c进行JOIN,然后再将得到的结果与表a进行JOIN。

如果STREAMTABLE省略掉了,那么Hive会在join中streams最右边的表。

5) LEFT,RIGHT和FULLOUTER joins的存在是为了提供更多对on语句中没有匹配的控制。

SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key);

6) 基于条件的LEFTOUTER JOIN优化(逻辑同样适合RIGHTand FULL joins)

表的join操作是在where语句之前执行的。

左连接时,左表中出现的字段值都会保留,右表没有连接上的字段值都为空。

例如:

SELECT a.val, b.val FROM a LEFT OUTERJOIN b ON (a.key=b.key)

WHERE a.ds='2015-06-21' ANDb.ds='2015-06-21';

执行顺序为:首先a和b表join,然后结果再通过where条件过滤,这样我们会发现在join过程中可能会输出大量结果,再对这些结果进行过滤操作,比较耗时。

进行优化时,可以将where条件放在on语句中,如下:

SELECT a.val, b.val FROM a LEFT OUTERJOIN b

ON (a.key=b.key AND b.ds='2015-06-21' ANDa.ds='2015-06-21');

?

?

Join 是不能交换位置的。无论是LEFT 还是 RIGHT join,都是左连接的,例如:

?

SELECT a.val1,a.val2

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hibernate关联映射 下一篇存储和文件管理

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: