一文解析大数据的JOIN

简介: 本文大部分理论和问题都从maxcomputer中得出,不同的计算引擎底层结构不同最后结果可能稍微不同,这一点需要注意,本文应该可以让你不再苦恼各种join,或者更加苦恼join。

本文大部分理论和问题都从maxcomputer中得出,不同的计算引擎底层结构不同最后结果可能稍微不同,这一点需要注意,本文应该可以让你不再苦恼各种join,或者更加苦恼join。

老生常谈的大小表问题

和传统sql语句类比,maxcomputer下的左右连接很奇怪,在官方文档中写着,碰到大小表问题,需要将大表放左边,小表放右边,和我们所理解的大小表问题的处理方式正好相反。

为了验证这一原因,我用一份两千万数据的大表和一份三万条数据的小表进行测试,为了避免数据泄露,本次测试包括下面全部测试样例都使用了CTE表达式。

正常的LEFTJOIN

首先说结果大表leftjoin小表,任务耗时3537ms,小表leftjoin大表,任务耗时4412ms。

从自带的logview查看二者的fuxijob,可以看出大表在右的时候,maxcomputer会采用hashjoin的方式直接将小表的数据和大表的数据关联;而当小表在右的时候,maxcomputer则会比正常多一步,既将两个数据流进行mergejoin,前者是将小表数据写入内存中进行join,后者则是排序join,耗时原因也就找到了。

排序后的LEFTJOIN

可实际业务中却也会出现左侧表为小表的情况,比如我们拿订单主表来关联订单子表的数据,如果提前以关联键排序,理论上来说,mergejoin会比hashjoin快一些,实际情况呢?

大表leftjoin小表,任务耗时6656ms,小表leftjoin大表,任务耗时4878ms,这真是可喜可贺,既然不能提升自己,那就打压一下对手,这里就不得不吐槽一下,一般大表在前,小表在后,是用大表卡小表的数据,用mapjoin中的join来指定大小表即可,为何要把其放在默认的逻辑上,反而是小表在前,会出现不用小表卡大表数据的情况。

这里也可能是本人接触的业务导致的偏见,继续聊join。

指定的MAPJOIN

maxomputer支持的mapjoin为左右连接和内连接,不支持全连接,但即使用mapjoin,leftouterjoin的时候左侧表也必须是大表,rightouterjoin相反,右侧为大表,innerjoin则可以显示指定何为小表,所以这里仅仅测试innerjoin的区别。

大表leftouterjoin小表,任务耗时7315ms,小表leftouterjoin大表,任务耗时8803ms;二者都是进行hashjoin,任务也只有两个M一个R,前者速度慢的原因,可能是我先查的后者,前者部分数据是从高速缓存读取的原因。

作为参考项,这里不使用mapjoin,单独join出了一份数据。大表leftouterjoin小表,任务耗时1499ms,小表leftouterjoin大表,任务耗时906ms;不用大惊小怪,因为maxcomputer有个类似oracle高速缓存的东西,也可以保存几次语义树解析相同的数据,需要的时候,直接拿出来。

为了进一步测试,过了一天后,我重新测试了非mapjoin的情况下,join的情况,大表在右时耗时7211ms,而小表在右则为8482ms.

到这里,大小表问题就告一段落,得出的结论也很简单,那就是大表在前,小表在后,如果数据需要出排序的数据,则可以提前排序,来让大小表的关系反过来,mapjoin的使用可有可无,基本上不是为了能够在关联的时候使用不等值表达式或者or逻辑,则可以舍弃mapjoin,其性能并不会因为使用了复杂的语法而多突出。

花里胡哨的JOIN

除了左右连接,内连接和隐式连接外,maxcomputer还提供了好几种花里胡哨的join,虽然可用性很低,但到了该使用的时候,也能带来不少的感官提升。

自然连接

作为自然连接,natutal join并不算稀奇,但他在odps sql的出现,不仅可以让开发少写几行代码,还可以让后来者在查看代码时,感到无地自容,这人的代码好牛逼,虽然只是sql,但我不知道他的关联是如何实现的。

其本质就是可以不去写on语句,只需要写natural join,执行时会自动根据左右表相同名称的字段进行inner join的操作。

半连接

半连接semi join,又一种朴实无华的join,其可以写为left semi join,可以返回左表满足右表指定条件的数据,和in相同;也可以写left anti join,可以返回左表不满足右表指定关联条件的数据,和not in相同。

IN和JOIN的效率

为了验证in和semi join在maxcomputer的执行效率,我用一张分区表进行了测试,大表数据大约1个g的数据量,小表数据为其一个分区有600多m的数据量,为了控制变量,在with阶段,我只选用了用户字段作为大小表数据,第一次semi join耗时3608ms,会有两个map任务,然后执行一个merge join任务,最后是有个reduce任务。

但在执行in的时候,语句进入resultcache直接得出结果,我在这里理解为二者经过优化后,实际执行的效率是相同的。

为了进一步测试,我用其他日期分区的再次进行in查询,发现执行为3517ms,查看job,发现in也是两个map任务,一个mergejoin任务,一个reduce任务,进一步验证了我的猜想。

这一理论也可以相应的延伸到其他的mapreduce为底层的sql语句,关系型数据库in比join慢是因为会创建临时表等操作,mapreduce并不会。

当然,我这里推荐使用的依旧还是semijoin,虽然可读性会差一些,只不过后续调整会方便很多,而且写的字数也比写in更少,效率就是王道!

Distributed MapJoin

分布式mapjoin(Distributed MapJoin),其为mapjoin的升级版,适合用作小表join大表的场景,不过核心都是减少大表侧的shuffle和排序操作。

只不过这个大小表有额外的定义,就是小表都得是在1g以上100g以下的数据,大表则是在10t以上的数据,这着实有点离大谱,目前本人还没有接触过这么大量级的表。

可以通过设置shard_count控制小表数据分片数,让小表数据分片(推荐一个分片量级为200m到500m)到各个计算节点处理;还可以通过replica_count控制小表数据的副本数,减少访问压力和避免节点失效后的整个任务失败,毕竟这一个任务跑起来消耗的资源可不少。

distmapjoin的真正使用场景,目前我无法想出来,但估计会发生的dws层,业务有一张大的维表和一张多数据源组层的dwd宽表。

SKEWJOIN HINT

sql join的时候有可能出现数据分布不均匀导致的长尾问题,skew join可以获取表的热点key,然后分别计算热点数据和非热点数据,加快执行效率。

显式指定和不指定的区别就在于,效率会更高,也就是方法三比方法一更快,方法二则居中。

当然,如果没有热点问题建议不要使用,它会让你的执行效率从3000ms变成10000ms,因为它的本质就是将热点数据和非热点数据打散,然后再unionall在一起。

动态过滤器

动态过滤器(dynamic filter)说是join的一种方式,反而不如说是一种join优化的思路,shuffle操作在海量数据下消耗的资源和时间都很多。

能够在join之前,将数据提前过滤掉的操作就被称为动态过滤器,官方文档中给出的思路是将小表侧的最小值和最大值得出,发送到大表侧,然后过滤掉大表侧的数据,规定中左侧为小表,而右侧为大表,但maxomputer定义join的时候,却是大表在左侧小表在右侧。

开启动态过滤器测试,发现他确实指定的small_table为小表,然后拿小表的最大值最小值去卡大表的数据,当大小表位置更换后则会报错。

官方文档也确实有如下内容(生产者为小表,消费者为大表,指大表消费小表生产的最大值最小值):

对于不同类型的JOIN语义,JOIN对象可担任的角色不同:

  • A JOIN B:A或B都能作为生产者、消费者。
  • A LEFT JOIN B:A只能作为生产者,B只能作为消费者。
  • A RIGHT JOIN B:A只能作为消费者,B只能作为生产者。
  • A FULL OUTER JOIN B:无法使用动态过滤器功能。

不懂就问,有大佬可以解释一下,为什么动态过滤器打开后,大小表的关系就反过来了?还是我测试的时候出现什么问题?

上面的思路和join方式套用在其他以mapreduce为基底的join上也是通用的.,当然就像我最后卡了bug一样,一段sql并不仅仅是写完就结束,他应该是优美的,尽自己可能优化过的。

相关实践学习
基于MaxCompute的热门话题分析
Apsara Clouder大数据专项技能认证配套课程:基于MaxCompute的热门话题分析
目录
相关文章
|
7月前
|
存储 分布式计算 Hadoop
Hadoop框架解析:大数据处理的核心技术
组件是对数据和方法的封装,从用户角度看是实现特定功能的独立黑盒子,能够有效完成任务。组件,也常被称作封装体,是对数据和方法的简洁封装形式。从用户的角度来看,它就像是一个实现了特定功能的黑盒子,具备输入和输出接口,能够独立完成某些任务。
|
7月前
|
人工智能 分布式计算 DataWorks
多模态数据处理新趋势:阿里云ODPS技术栈深度解析与未来展望
阿里云ODPS技术栈通过MaxCompute、Object Table与MaxFrame等核心组件,实现了多模态数据的高效处理与智能分析。该架构支持结构化与非结构化数据的统一管理,并深度融合AI能力,显著降低了分布式计算门槛,推动企业数字化转型。未来,其在智慧城市、数字医疗、智能制造等领域具有广泛应用前景。
617 6
多模态数据处理新趋势:阿里云ODPS技术栈深度解析与未来展望
|
9月前
|
人工智能 分布式计算 大数据
MCP、MaxFrame与大数据技术全景解析
本文介绍了 MCP 协议、MaxFrame 分布式计算框架以及大数据基础设施建设的相关内容。MCP(Model Context Protocol)是一种开源协议,旨在解决 AI 大模型与外部数据源及工具的集成问题,被比喻为大模型的“USB 接口”,通过统一交互方式降低开发复杂度。其核心架构包括 Client、Server、Tool 和 Schema 四个关键概念,并在百炼平台中得到实践应用。MaxFrame 是基于 Python 的高性能分布式计算引擎,支持多模态数据处理与 AI 集成,结合 MaxCompute 提供端到端的数据处理能力。
|
存储 搜索推荐 大数据
数据大爆炸:解析大数据的起源及其对未来的启示
数据大爆炸:解析大数据的起源及其对未来的启示
792 15
数据大爆炸:解析大数据的起源及其对未来的启示
|
存储 分布式计算 大数据
大数据揭秘:从数据湖到数据仓库的全面解析
大数据揭秘:从数据湖到数据仓库的全面解析
393 19
|
存储 SQL 分布式计算
湖仓一体架构深度解析:构建企业级数据管理与分析的新基石
【10月更文挑战第7天】湖仓一体架构深度解析:构建企业级数据管理与分析的新基石
1031 1
|
SQL 分布式计算 大数据
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(一)
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(一)
375 0
|
SQL 分布式计算 算法
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(二)
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(二)
272 0
|
5月前
|
机器学习/深度学习 传感器 分布式计算
数据才是真救命的:聊聊如何用大数据提升灾难预警的精准度
数据才是真救命的:聊聊如何用大数据提升灾难预警的精准度
394 14
|
6月前
|
机器学习/深度学习 运维 监控
运维不怕事多,就怕没数据——用大数据喂饱你的运维策略
运维不怕事多,就怕没数据——用大数据喂饱你的运维策略
345 0

推荐镜像

更多
  • DNS