Hive Sort Merge Bucket Map Join(大表关联)

本文介绍如何通过Hive桶(bucket)提高JOIN操作的效率。通过合理设置表的桶数及排序,可以有效减少JOIN的数据量,进而提升查询速度。文中通过实例展示了小表和大表在分桶和排序后的JOIN操作优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hive 桶

对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。
把表(或者分区)组织成桶(Bucket)有两个理由:

(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。

(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。

测试:一个4000万和一个5000多万的表Join,关联键数据倾斜,并且笛卡尔积,效果明显。

建立小表
create table lxw_test1(id int,name string,date_time string)  
clustered by(id) sorted by(id) into 10 buckets;  
建立大表
create table lxw_test2(id int,name string,date_time string)  
clustered by(id) sorted by(id) into 5 buckets;  

ps:
1.两个表关联键为id,需要按id分桶并且做排序,小表的分桶数是大表分桶数的倍数。
2.对于map端连接的情况,两个表以相同方式划分桶。处理左边表内某个桶的 mapper知道右边表内相匹配的行在对应的桶内。因此,mapper只需要获取那个桶 (这只是右边表内存储数据的一小部分)即可进行连接。这一优化方法并不一定要求 两个表必须桶的个数相同,两个表的桶个数是倍数关系也可以
3.桶中的数据可以根据一个或多个列另外进行排序。由于这样对每个桶的连接变成了高效的归并排序(merge-sort), 因此可以进一步提升map端连接的效率

启用桶表
set hive.enforce.bucketing = true;  
往小表中插入4000万条记录
  insert overwrite table lxw_test1  
  select id,name,null    
  from woa_all_user_info_his   
  where pt = '2012-05-28'  
  limit 40000000;  
往大表中插5000多万条记录(woa_all_user_info_his中有5000多万条记录)
 insert overwrite table lxw_test2  
 select id,name,date_time  
 from woa_all_user_info_his  
 where pt = '2012-05-28';  
设置Sort Merge Bucket Map Join的参数
set hive.optimize.bucketmapjoin = true;  
set hive.optimize.bucketmapjoin.sortedmerge = true;  
set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;  
ps:此时的状况是Bucket columns==Join Columns==Sort Columns,完全具备具备使用Sort Merge Bucket Map Join的条件。
查询
select /*+ mapjoin(b) */ count(1)  
from lxw_test1 a   
join lxw_test2 b  
on a.id = b.id   
测试结果:

包括insert数据,采用Sort Merge Bucket Map Join的方式耗时10分钟左右。

如果这两个表做普通的join,耗时1个多小时,还跑不完,最后只得Kill掉了!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值