一、Hive Join算法概述

Hive拥有多种join算法,包括Common Join,Map Join,Bucket Map Join,Sort Merge Buckt Map Join等,下面对每种join算法做简要说明:

Join 类型 本质 执行阶段 是否 Shuffle 是否 Reduce 对表要求 典型场景
Map Join 广播小表 Map 小表可放内存 小表 ↔ 大表
Bucket Map Join 分桶对齐 Map 两表 bucket 分桶表 join
Sort Merge Join 排序归并 Reduce 大表 ↔ 大表
Common Join Reduce Join Reduce 兜底方案

1、Common Join

Common Join是Hive中最稳定的join算法,其通过一个MapReduce Job完成一个join操作。Map端负责读取join操作所需表的数据,并按照关联字段进行分区,通过Shuffle,将其发送到Reduce端,相同key的数据在Reduce端完成最终的Join操作。如下图所示:

请添加图片描述

需要注意的是,sql语句中的join操作和执行计划中的Common Join任务并非一对一的关系,一个sql语句中的相邻的且关联字段相同的多个join操作可以合并为一个Common Join任务。
例如:

hive (default)> 
select 
    a.val,
    b.val,
    c.val
from a 
join b on (a.key = b.key1) 
join c on (c.key = b.key1)

上述sql语句中两个join操作的关联字段均为b表的key1字段,则该语句中的两个join操作可由一个Common Join任务实现,也就是可通过一个Map Reduce任务实现。

hive (default)> 
select 
    a.val, 
    b.val, 
    c.val 
from a 
join b on (a.key = b.key1) 
join c on (c.key = b.key2)

上述sql语句中的两个join操作关联字段各不相同,则该语句的两个join操作需要各自通过一个Common Join任务实现,也就是通过两个Map Reduce任务实现。

2、Map Join

Map Join算法可以通过两个只有map阶段的Job完成一个join操作。其适用场景为大表join小表。若某join操作满足要求,则第一个Job会读取小表数据,将其制作为hash table,并上传至Hadoop分布式缓存(本质上是上传至HDFS)。第二个Job会先从分布式缓存中读取小表数据,并缓存在Map Task的内存中,然后扫描大表数据,这样在map端即可完成关联操作。如下图所示:

请添加图片描述

3、Bucket Map Join

Bucket Map Join是对Map Join算法的改进,其打破了Map Join只适用于大表join小表的限制,可用于大表join大表的场景。

Bucket Map Join的核心思想是:若能保证参与join的表均为分桶表,且关联字段为分桶字段,且其中一张表的分桶数量是另外一张表分桶数量的整数倍,就能保证参与join的两张表的分桶之间具有明确的关联关系,所以就可以在两表的分桶间进行Map Join操作了。这样一来,第二个Job的Map端就无需再缓存小表的全表数据了,而只需缓存其所需的分桶即可。其原理如图所示:

请添加图片描述

bucket 数量满足:

大表 bucket 数 = 小表 bucket 数 × N

4、Sort Merge Bucket Map Join

Sort Merge Bucket Map Join(简称SMB Map Join)基于Bucket Map Join。SMB Map Join要求,参与join的表均为分桶表,且需保证分桶内的数据是有序的,且分桶字段、排序字段和关联字段为相同字段,且其中一张表的分桶数量是另外一张表分桶数量的整数倍。

SMB Map Join同Bucket Join一样,同样是利用两表各分桶之间的关联关系,在分桶之间进行join操作,不同的是,分桶之间的join操作的实现原理。Bucket Map Join,两个分桶之间的join实现原理为Hash Join算法;而SMB Map Join,两个分桶之间的join实现原理为Sort Merge Join算法。

Hash Join和Sort Merge Join均为关系型数据库中常见的Join实现算法。Hash Join的原理相对简单,就是对参与join的一张表构建hash table,然后扫描另外一张表,然后进行逐行匹配。Sort Merge Join需要在两张按照关联字段排好序的表中进行,其原理如图所示:

Hive中的SMB Map Join就是对两个分桶的

请添加图片描述

数据按照上述思路进行Join操作。可以看出,SMB Map Join与Bucket Map Join相比,在进行Join操作时,Map端是无需对整个Bucket构建hash table,也无需在Map端缓存整个Bucket数据的,每个Mapper只需按顺序逐个key读取两个分桶的数据进行join即可。

二、Spark join

  • Broadcast Hash Join(BHJ)

    • 小表 广播 到每个 Executor
    • 大表本地扫描
    • 内存中做 Hash Join
    • 无 Shuffle
  • Sort Merge Join(SMJ)

    • 两边都 Shuffle
    • 按 Join Key 排序
    • Merge 方式 Join
  • Shuffle Hash Join(SHJ)

    • 两边都 Shuffle
    • 小的一边构建 HashMap
    • 大的一边 probe
  • Broadcast Nested Loop Join(BNLJ)

    • 广播一边
    • 双层循环比对
  • Cartesian Product(笛卡尔积)

    • 全量两两组合
Join 类型 是否 Shuffle 依赖类型 是否切 Stage
Broadcast Hash Join 窄依赖
Broadcast Nested Loop Join 窄依赖
Sort Merge Join 宽依赖
Shuffle Hash Join 宽依赖
Full Outer Join ✅(只能 SMJ) 宽依赖
Cross Join 宽依赖
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐