Hive优化--SMB join

Sort MergeBucket Map Join(简称SMB Map Join)

基于Bucket Map Join。

条件要求

  • 参与join的表均为分桶表,且需保证分桶内的数据是有序的

  • 且分桶字段、排序字段和关联字段为相同字段

  • 且其中一张表的分桶数量是另外一张表分桶数量的整数倍

与Bucket Join对比

相同点:同样是利用两表各分桶之间的关联关系,在分桶之间进行join操作

不同点:

分桶之间的join操作的实现原理。

Bucket Map Join,两个分桶之间的join实现原理为Hash Join算法;

而SMB Map Join,两个分桶之间的join实现原理为Sort Merge Join算法。

特点

Hive中的SMB Map Join在进行Join操作时

Map端是无需对整个Bucket构建hash table,也无需在Map端缓存整个Bucket数据

每个Mapper只需按顺序逐个key读取两个分桶的数据进行join即可。

触发方式

两种触发方式,包括Hint提示和自动转换。Hint提示已过时,不推荐使用。

--启动Sort Merge Bucket Map Join优化
set hive.optimize.bucketmapjoin.sortedmerge=true;
--使用自动转换SMB Join
set hive.auto.convert.sortmerge.join=true;

例子

首先需要依据源表创建两个的有序的分桶表

order_detail建议分16个bucket

payment_detail建议分8个bucket

注意分桶个数的倍数关系以及分桶字段和排序字段

--订单表
hive (default)> 
drop table if exists order_detail_sorted_bucketed;
create table order_detail_sorted_bucketed(
    id           string comment '订单id',
    user_id      string comment '用户id',
    product_id   string comment '商品id',
    province_id  string comment '省份id',
    create_time  string comment '下单时间',
    product_num  int comment '商品件数',
    total_amount decimal(16, 2) comment '下单金额'
)
clustered by (id) sorted by(id) into 16 buckets
row format delimited fields terminated by '\t';

--支付表
hive (default)> 
drop table if exists payment_detail_sorted_bucketed;
create table payment_detail_sorted_bucketed(
    id              string comment '支付id',
    order_detail_id string comment '订单明细id',
    user_id         string comment '用户id',
    payment_time    string comment '支付时间',
    total_amount    decimal(16, 2) comment '支付金额'
)
clustered by (order_detail_id) sorted by(order_detail_id) into 8 buckets
row format delimited fields terminated by '\t';

然后向两个分桶表导入数据

--订单表
hive (default)> 
insert overwrite table order_detail_sorted_bucketed
select
* 
from order_detail
where dt='2020-06-14';

--分桶表
hive (default)> 
insert overwrite table payment_detail_sorted_bucketed
select
* 
from payment_detail
where dt='2020-06-14';

最后在重写SQL语句

hive (default)> 
select
    *
from order_detail_sorted_bucketed od
join payment_detail_sorted_bucketed pd
on od.id = pd.order_detail_id;
<think>好的,我现在需要详细理解Hive中的SMB Join(Sort Merge Bucket Join)的工作原理和实现机制。根据用户提供的引用内容,我首先需要整合这些信息,并确保正确应用LaTeX格式的数学表达式和代码块。 首先,SMB Join结合了分桶和排序机制,基于Sort Merge Join算法。根据引用[1],SMB Map Join的两个分桶之间的join使用Sort Merge Join算法。这说明SMB Join需要数据预先分桶并按关联字段排序。接下来,引用[2]提到Hash Join和Sort Merge Join的区别,其中Sort Merge Join需要两张表已经排序,这可能与Hive中的SMB Join相关。 然后,引用[3]和[5]提供了Hive配置参数,如开启分桶和自动转换Sort Merge Join的设置。这提示实现SMB Join需要正确配置这些参数。同时,引用[4]强调用户需自行确保数据已分桶和排序,否则结果可能不正确,这说明数据准备的重要性。 接下来,我需要将这些信息结构化,分步骤解释SMB Join原理,包括分桶、排序、合并阶段,以及配置要求和注意事项。同时,需要生成相关问题,可能涉及性能优化、与Hash Join的对比、配置参数和数据准备方法等。 在编写过程中,要确保所有数学表达式如分桶数$N$用$...$包裹,独立公式如哈希函数用$$...$$。代码块需正确使用Python或Hive SQL语法,并正确引用来源。最后,检查引用标识是否自然添加,并确保回答符合用户要求的层次结构。</think>### Hive SMB Join 原理及实现机制 #### 核心原理 Hive SMB(Sort Merge Bucket)Join 是一种基于**分桶表**和**排序合并算法**的高效关联操作,其核心分为以下步骤: 1. **分桶预处理** 参与 Join 的表需按关联字段进行**分桶**(Bucketing),即根据哈希函数将数据分配到固定数量的桶中。例如,若分桶数为$N$,则数据分布满足: $$ \text{bucket\_id} = \text{hash(join\_key)} \mod N $$ 此操作确保相同 join_key 的数据落入相同桶中[^1]。 2. **桶内排序** 每个桶内的数据需按关联字段**预先排序**。例如,表A和表B的分桶均按`user_id`升序排列,排序后每个桶内的数据局部有序[^4]。 3. **排序合并阶段** 执行 Join 时,Hive 直接对**相同编号的桶**进行排序合并操作。由于数据已预先排序,合并过程无需全表扫描,仅需线性遍历两个有序数据集即可完成匹配[^2]。 #### 实现机制 1. **配置参数** 需在 Hive 中启用以下配置: ```sql -- 开启分桶与自动转换 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; [^3][^5] ``` 2. **数据准备要求** - 两张表的分桶数必须**相同或成倍数关系**。 - 必须显式使用`CLUSTERED BY`和`SORTED BY`语句创建分桶表: ```sql CREATE TABLE table_a ( user_id INT, ... ) CLUSTERED BY (user_id) SORTED BY (user_id) INTO 8 BUCKETS; ``` 3. **执行过程** 当执行 SMB Join 时,Hive 会跳过常规的 Map 阶段 Shuffle 操作,直接对桶文件进行合并,从而减少网络传输和计算开销。 #### 优势与限制 - **优势** - 避免全表扫描,适用于大表关联。 - 减少内存消耗(无需构建哈希表)[^2]。 - **限制** - 数据必须严格按分桶和排序定义存储,否则结果错误[^4]。 - 仅支持等值关联(Equi-Join)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值