HiveSql语法优化四 :Bucket Map Join和Sort Merge Bucket Map Join优化

Bucket Map Join

之前的map join适用场景是大表join小表的情况,但是两张表都相对较大,若采用普通的Map Join算法,则Map端需要较多的内存来缓存数据,当然可以选择为Map段分配更多的内存,来保证任务运行成功。但是,Map端的内存不可能无上限的分配,所以当参与Join的表数据量均过大时,就可以考虑采用Bucket Map Join算法。

比如下面两张表进行join操作:

|---------------------------------|--------------------|
| 表名 | 大小 |
| order _detail | 1176009934(约1122M) |
| payment _detail | 334198480(约319M) |

首先需要依据源表创建两个分桶表,order_detail建议分16个bucket,payment_detail建议分8个bucket,注意分桶个数 的倍数关系以及分桶字段。

sql 复制代码
--订单表
hive (default)> 
drop table if exists order_detail_bucketed;
create table order_detail_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) into 16 buckets
row format delimited fields terminated by '\t';

--支付表
hive (default)> 
drop table if exists payment_detail_bucketed;
create table payment_detail_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) into 8 buckets
row format delimited fields terminated by '\t';

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

sql 复制代码
--订单表
hive (default)> 
insert overwrite table order_detail_bucketed
select
    id,
    user_id,
    product_id,
    province_id,
    create_time,
    product_num,
    total_amount   
from order_detail
where dt='2020-06-14';

--分桶表
hive (default)> 
insert overwrite table payment_detail_bucketed
select
    id,
    order_detail_id,
    user_id,
    payment_time,
    total_amount
from payment_detail
where dt='2020-06-14';

然后设置以下参数:

sql 复制代码
--关闭cbo优化,cbo会导致hint信息被忽略,需将如下参数修改为false
set hive.cbo.enable=false;
--map join hint默认会被忽略(因为已经过时),需将如下参数修改为false
set hive.ignore.mapjoin.hint=false;
--启用bucket map join优化功能,默认不启用,需将如下参数修改为true
set hive.optimize.bucketmapjoin = true;

最后在重写SQL语句,如下:

sql 复制代码
select /*+ mapjoin(pd) */
    *
from order_detail_bucketed od
join payment_detail_bucketed pd on od.id = pd.order_detail_id;

需要注意的是,Bucket Map Join的执行计划的基本信息和普通的Map Join无异,若想看到差异,可执行如下语句,查看执行计划的详细信息。详细执行计划中,如在Map Join Operator中看到 "BucketMapJoin: true",则表明使用的Join算法为Bucket Map Join。

sql 复制代码
explain extended select /*+ mapjoin(pd) */
    *
from order_detail_bucketed od
join payment_detail_bucketed pd on od.id = pd.order_detail_id;

Sort Merge Bucket Map Join

两张表都相对较大,除了可以考虑采用Bucket Map Join算法,还可以考虑SMB Join。相较于Bucket Map Join,SMB Map Join对分桶大小是没有要求的。

需要设置如下参数:

sql 复制代码
--启动Sort Merge Bucket Map Join优化
set hive.optimize.bucketmapjoin.sortedmerge=true;
--使用自动转换SMB Join
set hive.auto.convert.sortmerge.join=true;
相关推荐
搞AI的金鱼6 分钟前
skill agent workflow的区别
数据库
墨子夕28 分钟前
创新的潮汐——从科学发现到资本周期的百年规律(第二卷)
大数据·数据库·人工智能
Y38153266232 分钟前
印度电商数据采集教程:用 SerpBase 查 Flipkart/Myntra/Ajio 商品(附代码)
数据库·python
企业数字化笔记1 小时前
多租户配额怎么控制?用量口径、并发预留与超额处理的实现方法
java·数据库·spring boot
roman_日积跬步-终至千里1 小时前
【数据Agent论文·查询与语义|06】RAT-SQL:怎样把问题、表和字段真正关联起来?
数据库·sql·数据分析
盟接之桥1 小时前
盟接之桥谈线束数字化-按单入按单出:线束企业库存管理的破局之道
大数据·前端·网络·数据库·人工智能·制造
Nturmoils2 小时前
数据集成软件 KFS:多套业务库汇聚时,先把来源和口径理清
数据库
麦壳饼2 小时前
SonnetDB:批量写入的大小、背压与刷新策略
数据库·sonnetdb
weixin_460443562 小时前
Java+Linux私有化训考平台:服务、数据库与终端部署结构解析
java·linux·数据库·私有化部署·企业培训考试系统·企业考试系统
编程火箭车3 小时前
MySQL 拥抱 AI:向量、RAG、AutoML 全进了数据库
数据库·mysql·ai编程·向量数据库·rag·automl·mysql9