hive的join优化

1.join优化的介绍

hive的join优化一般是在data warehouse base(dwb)层出现,dwb层主要用于构建宽表,多表关联,需要join。hive的join分为map join 和reduce join,reduce join需要经过shuffle过程,涉及到IO流程,耗时较长,所以一般map join优化,map join分为一般的map join 、Bucket Map Join(分桶join)、SMB Join ( sort merge bucket map join)这三种。

2.map join

定义:每一个mapTask在读取数据的时候, 每读取一条数据, 就会和内存中班级表数据进行匹配, 如果能匹配的上, 将匹配上数据合并在一起, 输出即可。

好处: 将原有reduce join 问题全部都可以解决。

弊端:
1- 比较消耗内存;
2- 要求整个 Join 中, 必须的都有一个小表, 否则无法放入到内存中。

仅适用于: 小表 join 大表 | 大表 join 小表
在老版本(1.x以下)中, 需要将小表放置在前面, 大表放置在后面, 在新版本中, 无所谓。
建议, 如果明确知道那些表示小表, 可以优先将这些表, 放置在最前面。

如何使用呢?
set hive.auto.convert.join=true; – 开启 map join的支持 默认值为True
set hive.auto.convert.join.noconditionaltask.size=20971520; – 设置 小表数据量的最大阈值: 默认值为 20971520(20M)。
如果不满足条件, HIVE会自动使用 reduce join 操作。

下图是map join 的执行计划,只有Map Operator Tree,没有Reduce Operator Tree;而reduce joinl两者都有。
在这里插入图片描述

下图是reduce join 的执行计划,包括Map Operator Tree和Reduce Operator Tree。
在这里插入图片描述

3.Bucket Map Join

适用条件:
中型表 和 大表 join:
使用条件:
1- Join两个表必须是分桶表
2- 开启 Bucket Map Join 支持: set hive.optimize.bucketmapjoin = true;
3- 一个表的分桶数量是另一个表的分桶数量的整倍数
4- 分桶列 必须 是 join的ON条件的列
5- 必须建立在Map Join场景中

4 SMB Join ( sort merge bucket map join)

适用条件:
大表 和 大表 join
使用条件:
1- 两个表必须都是分桶表
2- 开启 SMB Join 支持:
set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
set hive.auto.convert.sortmerge.join.noconditionaltask=true;
3- 两个表的分桶的数量是一致的
4- 分桶列必须是 join的 on条件的列, 同时必须保证按照分桶列进行排序操作
– 开启强制排序
set hive.enforce.sorting=true;
– 在建分桶表使用: 必须使用sorted by()
5- 应用在Bucket Map Join 场景中
– 开启 bucket map join
set hive.optimize.bucketmapjoin = true;
6- 必须开启HIVE自动尝试使用SMB 方案:
set hive.optimize.bucketmapjoin.sortedmerge = true;

smb join的总结:
set hive.auto.convert.join=true;
set hive.auto.convert.join.noconditionaltask.size=20971520;
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;
set hive.enforce.sorting=true;
set hive.optimize.bucketmapjoin.sortedmerge = true;

smb join的建表语句:
create table course (cid string,c_name string,tid string) clustered by(cid) SORTED BY(cid) into 3 buckets row format delimited fields terminated by ‘\t’;

分桶的数量要根据文件大小和hive.auto.convert.join.noconditionaltask.size参数决定,两者相除得到最小的分桶数量。

加载数据:
insert overwrite table course select * from course_common cluster by(cid);
下图是smb join执行计划的图片,图中红线部分说明走的是smb join。
在这里插入图片描述

### Hive 中排序的相关用法 在 Hive 中,排序是一个常见的需求,通常通过 `ORDER BY` 和 `SORT BY` 来实现。以下是关于这两种方法的具体说明以及一些解决方案。 #### ORDER BY 的使用 `ORDER BY` 是一种全局排序的方式,它会对整个查询的结果集按照指定的列进行升序或降序排列。需要注意的是,由于其全局性质,在执行过程中可能会引发较大的性能开销,尤其是在大规模数据场景下[^1]。 ```sql SELECT column_name(s) FROM table_name ORDER BY column_name ASC|DESC; ``` 此语法中的 `ASC` 表示升序,默认情况下如果未指明顺序则默认为升序;而 `DESC` 则表示降序。 #### SORT BY 的应用 不同于 `ORDER BY` 的全表范围排序,`SORT BY` 只会在每个 reducer 内部完成局部排序工作。这意味着最终输出可能并非完全有序,但如果仅需每部分内部保持一定次序,则这种方法更为高效且资源消耗较少[^4]。 ```sql SELECT column_name(s) FROM table_name DISTRIBUTE BY another_column SORT BY column_name ASC|DESC; ``` 这里引入了一个额外的关键字——`DISTRIBUTE BY`,用来定义如何分配记录到不同的 reduce task 上面去。合理设置该参数可以帮助平衡负载并进一步提升效率。 #### 使用窗口函数辅助排序 当遇到复杂业务逻辑下的排序需求时,可以考虑利用 Hive 提供的强大功能之一—窗口函数(window function),如之前提到过的 row_number() over(partition by ... order by ...) 。这允许我们在分组的基础上再做独立排序,并赋予每一行唯一编号。 ```sql SELECT *, ROW_NUMBER() OVER (PARTITION BY group_col ORDER BY sort_col DESC) as rn FROM your_table; ``` 上述例子展示了基于某个字段(`group_col`)划分后的子集中按另一字段(`sort_col`)降序排列的过程,同时给定相应排名标记(rn)。 ### 解决排序过程中的常见问题 对于大数据量情况下的排序操作经常会面临诸如内存溢出等问题。此时可以从以下几个方面着手改进: - **调整输入文件大小**:尽可能减少单个 map/reduce 输入文件尺寸至合适区间内,避免因过大而导致计算失败的情况发生。 - **启用压缩机制**:通过对中间结果实施有效压缩措施降低 I/O 成本,提高整体作业运行速度[^3]。 - **优化 join 操作**:针对存在连接(join)运算的任务,应仔细评估参与关联双方的数据分布特性是否存在明显偏差(即所谓“热点”)现象,并采取适当策略加以缓解,例如重新设计分区键或是采用 skew join 技术等手段应对潜在的数据倾斜风险[^5]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值