<h2>
一,Hive中join的原理和机制
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
2
3
|
SELECT
|
a.id,a.dept,b.age
FROM
a
join
b
ON
(a.id = b.id);
Hive Map Join
MapJoin通常用于一个很小的表和一个大表进行join的场景,具体小表有多小,由参数hive.mapjoin.smalltable.filesize来决定,默认值为25M。满足条件的话Hive在执行时候会自动转化为MapJoin,或使用hint提示 /*+ mapjoin(table) */执行MapJoin。
如上图中的流程,首先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)、左关联(LEFT JOIN)、右关联(RIGHT JOIN)、全关联(FULL JOIN),还支持左半关联(LEFT SEMI JOIN)。
注意:Hive中Join的关联键必须在ON()中指定,不能在Where中指定。
数据准备:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
hive>
desc
|
lxw1234_a;
OK
id string
name
string
Time
taken: 0.094 seconds, Fetched: 2 row(s)
hive>
select
*
from
lxw1234_a;
OK
1 zhangsan
2 lisi
3 wangwu
Time
taken: 0.116 seconds, Fetched: 3 row(s)
hive>
desc
lxw1234_b;
OK
id string
age
int
Time