MAPJOIN来解决实际的问题

本文探讨如何通过MAPJOIN解决大数据集中的不等式Join问题,提高查询效率。通过实例展示,对于小表和不等式Join,MAPJOIN能有效避免笛卡尔积带来的性能瓶颈,实现快速匹配和高效计算。

最近开发中遇到几种应用,刚好使用MAPJOIN来解决实际的问题。

应用共同点如下:

1: 有一个极小的表<1000

2: 需要做不等值join操作a.x < b.y 或者 a.x like b.y等)

这种操作如果直接使用join的话语法不支持不等于操作,hive语法解析会直接抛出错误

果把不等于写到where里会造成笛卡尔积,数据异常增大,速度会很慢。甚至会任务无法跑成功~

根据mapjoin的计算原理,MAPJION会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配。这种情况下即使笛卡尔积也不会对任务运行速度造成太大的效率影响。

而且hivewhere条件本身就是在map阶段进行的操作,所以在where里写入不等值比对的话,也不会造成额外负担。

如此看来,使用MAPJOIN开发的程序仅仅使用map一个过程就可以完成不等值join操作,效率还会有很大的提升。

问题解决~~

示例代码如下:

 select/*+MAPJOIN(a) */

 a.start_level,b.*

 fromdim_level a

 join(select * fromtest) b

 whereb.xx>=a.start_level and b.xx<end_level;

MAPJOIN 结合 UNIONALL

 

原始sql

select a.*,coalesce(c.categoryid,’NA’) asapp_category

from (select * from t_aa_pvid_ctr_hour_js_mes1

) a

left outer join

(select * fromt_qd_cmfu_book_info_mes

) c

on a.app_id=c.book_id;

 

速度很慢,老办法,先查下数据分布。

select *

from

(selectapp_id,count(1) cnt

fromt_aa_pvid_ctr_hour_js_mes1

group by app_id) t

order by cnt DESC

limit 50;

 

数据分布如下:

NA      617370129

2       118293314

1       40673814

d       20151236

b       1846306

s       1124246

5       675240

8       642231

6       611104

t       596973

4       579473

3       489516

7       475999

9       373395

107580  10508

 

我们可以看到除了NA是有问题的异常值,还有appid=1~9的数据也很多,而这些数据是可以关联到的,所以这里不能简单的随机函数了。而t_qd_cmfu_book_info_mes这张app库表,又有几百万数据,太大以致不能放入内存使用mapjoin。

 

解决方案:

select a.*,coalesce(c.categoryid,’NA’) asapp_category

from –if app_id isnot number value or <=9,then not join

(select * fromt_aa_pvid_ctr_hour_js_mes1

where cast(app_id asint)>9

) a

left outer join

(select * fromt_qd_cmfu_book_info_mes

where cast(book_id asint)>9) c

on a.app_id=c.book_id

union all

select /*+ MAPJOIN(c)*/

a.*,coalesce(c.categoryid,’NA’) as app_category

from –if app_id<=9,use map join

(select * fromt_aa_pvid_ctr_hour_js_mes1

wherecoalesce(cast(app_id as int),-999)<=9) a

left outer join

(select * fromt_qd_cmfu_book_info_mes

where cast(book_id asint)<=9) c

–if app_id is notnumber value,then not join

on a.app_id=c.book_id

 

先将appid=NA和1~9的数据存入一组,并使用mapjoin与维表(维表也限定appid=1~9,这样内存就放得下了)关联,而除此之外的数据存入另一组,使用普通的join,最后使用union all 放到一起

 












在阿里云大数据处理环境中,MapJoin 是一种用于优化表连接操作的技术,尤其适用于大表与小表进行关联的场景。通过将小表加载到内存中,MapJoin 能够避免传统的 Reduce 阶段,从而显著提升查询性能。以下是关于阿里云 MapJoin 的使用指南及常见问题。 ### MapJoin 的使用方法 在阿里云 DataWorks 或 MaxCompute 环境中使用 MapJoin 时,可以通过在 SQL 语句中添加 Hint 来启用该功能。例如,当一个大表需要与一个较小的维度表进行关联时,可以使用如下语法: ```sql SELECT /*+ MAPJOIN(small_table) */ * FROM large_table JOIN small_table ON large_table.id = small_table.id; ``` 上述语句中,`/*+ MAPJOIN(small_table) */` 是一个优化器提示,用于指示系统将 `small_table` 加载到内存中,并在 Map 阶段完成连接操作。这种方式可以有效避免数据倾斜问题,提高查询效率。 在某些情况下,可能需要调整 MapJoin 的内存大小以适应不同规模的小表。这可以通过设置相关参数来实现,例如: ```sql SET odps.sql.mapjoin.memory=512; ``` 此设置将 MapJoin 的内存限制调整为 512MB,确保小表可以被完整加载到内存中,从而顺利完成连接操作。 ### 常见问题解决方案 1. **小表无法完全加载到内存中** 如果小表的大小超过了 MapJoin 的内存限制,可能会导致任务失败。此时可以尝试增加 MapJoin 的内存大小,或者考虑将小表进一步过滤或聚合,以减少其数据量。 2. **MapJoin 不生效** 如果发现 MapJoin 没有按预期工作,可能是由于 SQL 语句中的 Hint 格式不正确,或者小表的数据量过大导致系统自动放弃使用 MapJoin。检查 Hint 的语法是否正确,并确保小表的大小适合内存加载。 3. **数据倾斜问题仍然存在** 尽管 MapJoin 可以缓解数据倾斜问题,但在某些情况下,如果大表的数据分布不均匀,仍然可能导致性能瓶颈。此时可以考虑对大表进行分区或分桶处理,以进一步优化查询性能。 4. **MapJoin 的适用场景有限** MapJoin 主要适用于大表与小表的连接操作。对于两个大表之间的连接,建议使用普通的 Join 操作,并结合其他优化手段,如分区、分桶等。 ### 性能优化建议 - **合理选择小表**:确保参与 MapJoin 的表确实是较小的表,以便能够完全加载到内存中。 - **监控资源使用情况**:通过监控任务的资源使用情况,及时调整 MapJoin 的内存大小,避免因内存不足而导致任务失败。 - **结合其他优化技术**:如数据分区、分桶等,进一步提升查询性能。 通过合理使用 MapJoin 并结合其他优化手段,可以在阿里云环境中显著提升大数据处理的效率和稳定性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值