返回介绍

Hive Join 的原理与机制

发布于 2024-06-23 16:10:22 字数 8092 浏览 0 评论 0 收藏 0

Hive 中 的 Join 可分为 Common Join(Reduce阶段完成join)和 Map Join(Map 阶段完成 join)。

Hive Common Join

如果不指定 MapJoin 或者不符合 MapJoin 的条件,那么 Hive 解析器会默认执行 Common Join,即在 Reduce 阶段完成 join。整个过程包含 Map、Shuffle、Reduce 阶段。

Map 阶段

读取源表的数据,Map 输出时候以 Join on 条件中的列为 key,如果 Join 有多个关联键,则以这些关联键的组合作为 key;Map 输出的 value 为 join 之后所关心的( select 或者 where 中需要用到的)列,同时在 value 中还会包含表的 Tag 信息,用于标明此 value 对应哪个表。

Shuffle 阶段

根据 key 的值进行 hash,并将 key/value 按照 hash 值推送至不同的 reduce 中,这样确保两个表中相同的 key 位于同一个 reduce 中。

Reduce 阶段

根据 key 的值完成 join 操作,期间通过 Tag 来识别不同表中的数据。

以下面的HQL为例,图解其过程:

  1. SELECT a.id,a.dept,b.age
  2. FROM a join b
  3. ON (a.id = b.id);

hive join 原理

Hive Map Join

MapJoin 通常用于一个很小的表和一个大表进行 join 的场景,具体小表有多小,由参数hive.mapjoin.smalltable.filesize 来决定,默认值为 25M。满足条件的话 Hive 在执行时候会自动转化为 MapJoin,或使用 hint 提示 /*+ mapjoin(table) */ 执行 MapJoin。

hive map join 原理

如上图中的流程,首先 Task A 在客户端本地执行,负责扫描小表 b 的数据,将其转换成一个HashTable 的数据结构,并写入本地的文件中,之后将该文件加载到 DistributeCache 中。

接下来的 Task B 任务是一个没有 Reduce 的 MapReduce,启动 MapTasks 扫描大表 a,在 Map 阶段,根据 a 的每一条记录去和 DistributeCache 中 b 表对应的 HashTable 关联,并直接输出结果,因为没有 Reduce,所以有多少个 Map Task,就有多少个结果文件。

注意:Map JOIN 不适合 FULL/RIGHT OUTER JOIN。

Join 的几种类型

Hive 中 join 有 4 种类型。分别是:

  1. 内关联(inner join 或者简写成 join)
  2. 左关联(left outer join 或者简写成 left join)
  3. 右关联(right outer join 或者简写成 right join)
  4. 全关联(full outer join 或者简写成 full join)

hive join 的几种类型

下面以例子介绍各个 Join 的用法。假如有两个表,一个是客户表(表名:customers),一个是订单表(表名:order)。

客户表数据如下:

IDNameAgeAddressSalary
1Ross32Ahmedabad2000
2Rachel25Delhi1500
3Chandler23Kota2000
4Monika25Mumbai6500
5Mike27Bhopal8500
6Phoebe22MP4500
7Joey24Indore10000

订单表数据如下:

OIDDateCustomer_IDAmount
1022016-10-08 00:00:0033000
1002016-10-08 00:00:0031500
1012016-11-20 00:00:0021560
1032015-05-20 00:00:0042060

内关联(inner join、join)

常规 join,类似交集,只显示关联成功的行。如上图所示,它会按照关联条件把左表与右表两者的交集提取出来,作为最终结果。

  1. hive> SELECT c.ID, c.NAME, c.AGE, o.AMOUNT
  2. FROM CUSTOMERS c JOIN ORDERS o
  3. ON (c.ID = o.CUSTOMER_ID);

执行后结果如下:

IDNameAgeAmount
3Chandler231300
3Chandler231500
2Rachel251560
4Monika252060

左关联(left outer join、left join)

left [join] join 关键字前面的表作为主表,和其他表进行关联,返回记录和主表的记录数一致,关联不上的字段会被置为 NULL。 另外是否指定 outer 关键字,对查询结果无影响。

  1. hive> SELECT c.ID, c.NAME, o.AMOUNT, o.DATE
  2. FROM CUSTOMERS c
  3. LEFT OUTER JOIN ORDERS o
  4. ON (c.ID = o.CUSTOMER_ID);

结果如下:

IDNameAmountDate
1RossNULLNULL
2Rachel15602016-11-20 00:00:00
3Chandler30002016-10-08 00:00:00
3Chandler15002016-10-08 00:00:00
4Monika20602015-05-20 00:00:00
5MikeNULLNULL
6PhoebeNULLNULL
7JoeyNULLNULL

右关联(right outer join、right join)

和左外关联相反,以 right [outer] join 关键词后面的表作为主表,和前面的表做关联,返回记录数和主表一致,关联不上的字段为 NULL。是否指定 outer 关键字,对查询结果无影响。

  1. hive> SELECT c.ID, c.NAME, o.AMOUNT, o.DATE
  2. FROM CUSTOMERS c
  3. RIGHT OUTER JOIN ORDERS o
  4. ON (c.ID = o.CUSTOMER_ID);

结果如下:

IDNameAmountDate
3Chandler13002016-10-08 00:00:00
3Chandler15002016-10-08 00:00:00
2Rachel15602016-11-20 00:00:00
4Monika20602015-05-20 00:00:00

全关联(full outer join、full join)

全关联的原理是先左关联再右关联,然后把结果用 union all 合并在一起,关联不到的字段被自动置为 NULL。是否指定 outer 关键字,对查询结果无影响。

  1. hive> SELECT c.ID, c.NAME, o.AMOUNT, o.DATE
  2. FROM CUSTOMERS c
  3. FULL OUTER JOIN ORDERS o
  4. ON (c.ID = o.CUSTOMER_ID);

执行结果如下:

IDNameAmountDate
1RossNULLNULL
2Rachel15602016-11-20 00:00:00
3Chandler30002016-10-08 00:00:00
3Chandler15002016-10-08 00:00:00
4Monika20602015-05-20 00:00:00
5MikeNULLNULL
6PhoebeNULLNULL
7JoeyNULLNULL
3Chandler30002016-10-08 00:00:00
3Chandler15002016-10-08 00:00:00
2Rachel15602016-11-20 00:00:00
4Monika20602015-05-20 00:00:00

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文