前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >sparksql优化的奇技淫巧(一次惊掉下巴的优化)

sparksql优化的奇技淫巧(一次惊掉下巴的优化)

作者头像
数据仓库践行者
发布2023-03-06 14:51:52
7100
发布2023-03-06 14:51:52
举报

先给看效果:

刚重跑的,知道能加快,但没想到能加快这么多

先说下数据量吧,每天20亿+

开心开心开心开心

这次的优化灵感,来自于牛逼的群友们

源于群里一个同学的疑惑,看图:

只能说,以后大家看到一个看似没用的条件的时候,千万不要随便删除,这个条件很有可能起到了优化的大作用。

由于群里的同学公司用的spark版本比较早,我们知道原因就好,暂且不细去追究。

可是,这个思路提醒了我,我们有个任务,也可以用这个方法来优化,并且走的是另外一个原理。

之前有写一篇 SparkSql不同写法的一些坑(性能优化) 里面的第二种情况:

myudf是自定义的函数,如果我们这么用的话,这个函数会执行三遍。

这样在某些情况下是非常低效的,比如我们现在的数据,一个超大超复杂各种嵌套的json串,需要写udf从中解析出对应的数据,有的还需要输出排序的结果,并且字段巨多(小100个),那就得执行100次。

我们或许会想到要这样写:

代码语言:javascript
复制
 select 
   atmp[0] as a1,
   atmp[1] as a2,
   atmp[2] as a3 
   ...
   atmp[100] as a100
 from 
 (select 
   myudf(A,B) as atmp
 from testdata2
 ) tmp

在sparksql branch3.3 这样改写完全没问题,会判断出自定义的函数是昂贵的计算,默认不给合并;

但在3.3以下的版本中,CollapseProject(合并Project) 优化器会合并,导致最终的计算还是:

代码语言:javascript
复制
select 
   myudf(A,B)[0] as a1,
   myudf(A,B)[1] as a2,
   myudf(A,B)[2] as a3 
   ...
   myudf(A,B)[100] as a100
 from testdata2

这样的过程。

我们公司的spark目前还没完全把3.3版本的一些优化给合并过来,所以就会出现这样的问题。

之前的做法是:

代码语言:javascript
复制
SET spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.CollapseProject;

把CollapseProject优化器关掉,其实关优化器,也会有其他问题:一个写表的逻辑,sql是很复杂的,如果关掉,可能其他需要用到该优化器的模块就没办法用了。

现就没必要关了,把rand()<2这样的条件给用上,写法如下:

代码语言:javascript
复制
 select 
   if(helpcol<2,atmp[0],xxx) as a1,
   atmp[1] as a2,
   atmp[2] as a3 
   ...
   atmp[100] as a100
 from 
 (select 
   myudf(A,B) as atmp,
   rand() as helpcol   
 from testdata2
 ) tmp

上面写法的重点是,加一个 非deterministic(不确定)的辅助列,并且在外层引用这个列。这里用的是rand()函数,内查询用rand() as helpcol ,外查询用if(helpcol<2,atmp[0],xxx) as a1, 并且只用到一列上就可以,这个只是保证外查询和内查询有这个非deterministic的重合列,这样在这个模块的查询语句中CollapseProjet优化器就失效了。

ps:关于表达式的确定性(deterministic)的理解,可以看这篇

Spark sql Expression的deterministic属性

下面看这种用法执行计划上的效果:

在我们的这个案例上,运行时长的效果怎么样呢?

真的是惊掉下巴!!!

还能说什么呢?

你可能会有疑惑:我是怎么知道这么写可以呢?

哈哈,因为我对sparksql够熟悉啊

这个优化还有其他的解决方案吗?

有啊,写udtf函数,但我不想写udtf,因为udf更简单,哈哈哈哈

关于udtf为什么能做到优化?之前有写一篇udtf函数的原理,虽然是hive版本的,但是spark也适用,差不多一个原理:

你真的了解Lateral View explode吗?--源码复盘


精读源码,是一种有效的培养专长的方式~~

如果你想培养自己的优势

通过优势来提高自己在职场的影响力

但不知道如何开始

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据仓库践行者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档