通俗易懂的Hive join几种形式原理详解

表的Join是数据分析处理过程中必不可少的操作,Hive同样支持Join的语法,Hive Join的底层还是通过MapReduce来实现的,Hive实现Join时,为了提高MapReduce的性能,提供了多种Join方案来实现,例如适合小表Join大表的Map Join,大表Join大表的Reduce Join,以及大表Join的优化方案Bucket Join等。

1 Map Join

  • 应用场景

适合于小表join大表或者小表Join小表

  • 原理

  • 将小的那份数据给每个MapTask的内存都放一份完整的数据,大的数据每个部分都可以与小数据的完整数据进行join
  • 底层不需要经过shuffle,需要占用内存空间存放小的数据文件

    首先是在本地客户端生成的Task A,是一个MapReduce Local Task,负责把小表数据从HDFS读取到内存哈希表。读取后,它会将内存中的哈希表序列化为磁盘上的文件,并将哈希表文件压缩为tar文件
    接下来是Task B,该任务是一个没有Reduce的MapReduce任务,启动的时候,上一步骤的tar文件会被放到Hadoop分布式缓存中,Hadoop分布式缓存将把tar文件填充到每个Mapper的本地磁盘并解压缩该文件。然后mapper可以将哈希表文件反序列化回内存,并像以前一样执行join工作,也就是根据大表中的每一条记录去和DistributeCache中小表对应的HashTable关联,并直接输出结果。

        关于自动优化:对于MapJoin,查询处理器应该知道大表是哪个输入表。在执行阶段,其他输入表将被识别为小表,这些表需要保存在内存中。但是,一般来说,查询处理器在编译期间不知道输入文件的大小(即使有统计数据),因为某些表可能是由子查询生成的中间表。所以查询处理器只能在执行期间计算出输入文件的大小。

  • 使用
  1. 尽量使用Map Join来实现Join过程
  2. Hive中默认自动开启了Map Join

-- 默认已经开启了Map Join

hive.auto.convert.join=true

Hive中判断哪张表是小表及限制

  • LEFT OUTER JOIN的左表必须是大表
  • RIGHT OUTER JOIN的右表必须是大表
  • INNER JOIN左表或右表均可以作为大表
  • FULL OUTER JOIN不能使用MAPJOIN
  • MAPJOIN支持小表为子查询
  • 使用MAPJOIN时需要引用小表或是子查询时,需要引用别名
  • 在MAPJOIN中,可以使用不等值连接或者使用OR连接多个条件
  • 在MAPJOIN中最多支持指定6张小表,否则报语法错误

Hive中小表的大小限制

-- 2.0版本之前的控制属性
hive.mapjoin.smalltable.filesize=25M
-- 2.0版本开始由以下参数控制
hive.auto.convert.join.noconditionaltask.size=512000000

2 Reduce Join

应用场景

       适合于大表Join大表

原理

  • 将两张表的数据在shuffle阶段利用shuffle的分组来将数据按照关联字段进行合并
  • 必须经过shuffle,利用Shuffle过程中的分组来实现关联

过程

1. Map阶段:构建(key(tag),value),key这里后面的数字是tag,后面在reduce阶段用来区分来自于那个表的数据,对key求hashcode设为hivekey;
2. Shuffle阶段:如果key在不同机器上,会通过网络传输把hivekey相同的数据汇集到一台机器;
3. Reduce阶段:把tag=1的内容(value),都加到tag=0的后面,合并输出。

 

使用

Hive会自动判断是否满足Map Join,如果不满足Map Join,则自动执行Reduce Join

3 Bucket Join

应用场景

适合于大表Join大表

原理

将两张表按照相同的规则将数据划分,根据对应的规则的数据进行join,减少了比较次数,提高了性能

  1. 使用

Bucket Join

  • 语法:clustered by colName
  • 参数

-- 开启分桶join
set hive.optimize.bucketmapjoin = true;

2 要求

分桶字段 = Join字段 ,桶的个数相等或者成倍数

Sort Merge Bucket Join(SMB):基于有序的数据Join

  • 语法:clustered by colName sorted by (colName)
  • 参数

-- 开启分桶SMB join
set hive.optimize.bucketmapjoin = true;
set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
set hive.auto.convert.sortmerge.join.noconditionaltask=true;

要求

分桶字段 = Join字段 = 排序字段 ,桶的个数相等或者成倍数

4 拓展Hive其他几种算子实现

Hive group by原理

默认设置了hive.map.aggr=true,会在mapper端先group by一次,最后把结果merge起来,为了减少reducer处理的数据量。

 Hive distinct 实现原理

只有一个distinct实现原理如下图:

有多个distinct字段,有两种实现方式,第一种同上,第二种对不同distinct字段编号膨胀,group by字段作为partition key,最后在reduce阶段保存LastKey区分不同的key。

Hive 排序原理

  • order by 是全局排序,可能性能会比较差,orderby生成一个reduce,数据量比较大是有性能瓶颈;
  • sort by分区内有序,往往配合distribute by来确定该分区都有那些数据;
  • distribute by确定了数据分发的规则,满足相同条件的数据被分发到一个reducer,常用于解决小文件问题;
  • cluster by当distribute by和sort by字段相同时,可以使用cluster by代替distribute by和sort by,但是cluster by默认是升序,不能指定排序方向。
     

  • 4
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值