Hive中Join的使用入门 & Common Join与Map Join原理深度剖析

来源:互联网 发布:mysql触发器查询语句 编辑:程序博客网 时间:2024/05/18 09:03

Hive中JOIN的使用入门

Hive中join的用法

Hive中Join的通常使用有以下几种:

  1. inner join 等值连接
  2. left join
    right join
    full join
  3. left semi join
  4. cross join(笛卡尔积)
  5. mulitiple(一般来说是多个表进行join)

数据准备:

join_a.txt:    1    zhangsan    2    lisi    3    wangwujoin_b.txt:    1    30    2    29    4    21

创建a表并导入数据:

create table a(id int,name string)row format delimited fields terminated by '\t';hive>load data local inpath '/opt/data/join_a.txt' overwrite into table a;

创建b表并导入数据:

create table b(id int,age int)row format delimited fields terminated by '\t';hive>load data local inpath '/opt/data/join_b.txt' overwrite into table b;

进行测试

  • 普通Join
hive>select a.id,a.name,b.age from a join b on a.id=b.id

执行结果:
这里写图片描述

  • 左外连接
hive>select a.id,a.name,b.age from a left join b on a.id=b.id

执行结果:
这里写图片描述

  • 右外连接
hive>select a.id,a.name,b.age from a right join b on a.id=b.id

执行结果:
这里写图片描述
因为取的是a.id 所以id为NULL

  • 全连接
hive>select a.id,a.name,b.age from a full join b on a.id=b.id

执行结果:
这里写图片描述

  • 笛卡尔(笛卡尔后面不需要加条件)
hive>select a.id,a.name,b.age from a cross join b;

执行结果:
这里写图片描述

Common Join和Map Join的MapReduce实现

地址:http://blog.csdn.net/lemonzhaotao/article/details/78209708
由于Hive的底层就是MapReduce,因此通过MapReduce的自己编程,可以进一步了解两者的执行原理,有助于Hive的学习

Common Join实现原理深度剖析

Common Join即传统思路实现Join,性能较差 因为涉及到了shuffle的过程
common join/shuffle join/reduce join (都是指同一个)

执行流程

这里写图片描述

实现思路(最古老的实现思路)

有a表和b表
以这句SQL为思路: select a.id,a.name,b.age from a join b on a.id=b.id 去实现
通过两个表的id去进行join

1) map 读取 a表  ==> <id, (name)>    <1,(zhangsan)>    <2,(lisi)>    <3,(wangwu)>2) map 读取 b表     ==> <id, (age)>    <1,(30)>    <2,(29)>    <4,(21)>3) shuffle: hash(key)       <1,(zhangsan,30)>    <2,(lisi,29)>       <3,(wangwu)>    <4,(21)>4) reduce    1,(zhangsan,30)     2,(lisi,29)     3,(wangwu)    4,(21)

这种执行流程,会造成的问题

  1. 数据倾斜
    产生该现象的根本原因:某一个key太多,从而导致某一个task的数据量特别大
  2. shuffle
    一旦出现shuffle,性能就会下降很多(不管是在hadoop还是spark中都是一样)
    因此在做spark开发的过程中,有一个原则:能避免不使用shuffle就不使用产生shuffle的算子
    因为shuffle最耗费性能

MapJoin实现原理深度剖析

mapjoin 也叫作 boardcast join
map join不会有reduce阶段和shuffle阶段

执行流程

这里写图片描述

  1. 先启动Task A;Task A去启动一个MapReduce的local task;通过该local task把small table data的数据读取进来;之后会生成一个HashTable Files;之后将该文件加载到分布式 缓存中来;
  2. 启动MapJoin Task,去读大表的数据,每读一个就会去和Distributed Cache中的数据去关联一次,关联上后进行输出
    整个阶段,没有reduce 和 shuffle

原理

  1. 将小表的数据加载到内存中
  2. 没有shuffle过程
  3. 缺点:内存(如果小表过大,可能会出现OOM)

通过执行计划深度剖析Common Join和MapJoin的区别

通过日志打印的信息去对比两种Join操作
非常重要,需要会画两个join的图、知道两者的原理

数据准备

  • 数据准备:
dept.txt10 ACCOUNTINGNEW YORK20 RESEARCHDALLAS30 SALESCHICAGO40 OPERATIONSBOSTON
  • 创建dept表
hive>create table dept(deptno int, dname string, loc string) row format delimited fields terminated by '\t';
  • 导入数据到dept表
hive>load data local inpath '/opt/data/dept.txt' overwrite into table dept;

测试

hive低版本使用mapjoin必须这样写:
得说明d是小表:/+MAPJOIN(d)/ 告诉hive d是小表

hive>select /*+MAPJOIN(d)*/ e.empno, e.ename, d.dname from emp e join dept d on e.deptno=d.deptno;  

注意:在hive中看执行计划是十分重要的一个技能

网址:
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Explain

语法:

EXPLAIN [EXTENDED|DEPENDENCY|AUTHORIZATION] query
  • hive.auto.convert.join参数设置
    hive.auto.convert.join=true的意思为:
    hive自动会把普通的join转换为mapjoin,也就是哪个表大哪个表小 hive自动会我们进行转换
    为了测试看到更好的效果,我们需要将这个值设置为false

  • 给参数设置值

hive>set hive.auto.convert.join=false;
  • 查看common join执行计划
hive>explain select  e.empno, e.ename, d.dname from emp e join dept d on e.deptno=d.deptno;

打印的信息:
这里写图片描述
这里写图片描述

打印出信息的部分说明:
TableScan 表示去读表
Filter Operator 表示过滤操作 即 e.deptno=d.deptno
value expressions 表示输出的value字段有哪些

  • 查看map join执行计划
hive>set hive.auto.convert.join=true;hive>explain select  e.empno, e.ename, d.dname from emp e join dept d on e.deptno=d.deptno;

打印的执行计划信息:
这里写图片描述
这里写图片描述

通过打印在控制台的日志去查看map join:
这里写图片描述

starting to launch local task
对应 mapreduce local task

Dump ….. hashtable
将hashtable sink出来了(输出出来)

uploaded ….
将hashtable 上传到分布式缓存中了 这个就是小表的流程

End of local task
结束了local task

MapredLocal task successfully
map local task执行成功

Launching Job 1 out of 1
启动一个job

number of mappers:1 number of reducers:0
没有reducer,mapper数量为1

重点:
对于普通join 会生成2个stage
对于mapjoin 会生成3个stage

原创粉丝点击