java case when用法_sql case when 嵌套

java case when用法_sql case when 嵌套前几天在客户环境遇到一个Spark“CASEWHEN”语句的性能优化问题。客户那边通过一个“时间范围筛选”控件来动态修改图表的数据。其很多指标的计算逻辑类似于:CASEWHEN`bizdate`BETWEEN’2020-09-06’AND’2020-09-13’THEN`sales_amount`ELSE0ENDCASEWHEN语句有些类似于编程语言中的Switch语句,当这里的…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前几天在客户环境遇到一个Spark “CASE WHEN”语句的性能优化问题。

客户那边通过一个“时间范围筛选”控件来动态修改图表的数据。其很多指标的计算逻辑类似于:

CASE

WHEN `bizdate`

BETWEEN ‘2020-09-06’ AND ‘2020-09-13’

THEN `sales_amount`

ELSE 0

END

CASE WHEN语句有些类似于编程语言中的Switch语句,当这里的 WHEN从句只有一个的时候,可以简化为IF语句(或者 IF-ELSE 语句)。

于是想:对于Spark(客户用的是2.4.x版本), Spark会不会把这种只有一个WHEN分支的 CASE WHEN 语句优化为IF语句呢? 于是试了一下性能,发现如果修改上面的SQL为:

IF(`bizdate`

BETWEEN ‘2020-09-06’ AND ‘2020-09-13’,

`sales_amount`,

0

)

那么执行速度将减少为原来的一半! 原来Spark 2.4并没有做这个优化,突然感到有些兴奋。那是不是我的机会来了。

首先、这个应该是一个比较简单的优化,比如我是否可以通过增加一个Spark的优化器规则,来自动把一个分支的CASE WHEN转为IF,看着好像不难。

不过在真正动手前,先看看: Spark的最新版本是否已经有了这个修改?

于是先看看 CASE When 语句的实现,发现最新的发布版本(Spark 3.0.1)的代码是这样的:

override def doGenCode(ctx: CodegenContext,

ev: ExprCode): ExprCode = {

if (branches.length == 1) {

// If we have only single branch we can use If expression and its codeGen If(

branches(0)._1,

branches(0)._2,

elseValue

.getOrElse(Literal.create(null, branches(0)._2.dataType)))

.doGenCode(ctx, ev)

} else {

multiBranchesCodegen(ctx, ev)

}

}

发现,在Spark转化执行代码为 Java时(doGenCode),其已经对于分支为1的情况,做了自动转化为 IF 语句的操作。

虽然我感觉更适合放在优化器中做,不过直接修改 CaseWhen 这个类的 doGenCode() 可能简单直接! 从这个修改的PR的diff来看也确实如此(只改了几行代码):

首先,发现其 “Fix Version/s: 3.0.0”,果然是3.0才优化的。

其描述问题时的重现步骤:

val df = spark.range(10000000000L).withColumn(“x”, rand)

val resultA = df.withColumn(“r”, when($”x” < 0.5, lit(1)).otherwise(lit(0))).agg(sum($”r”))

val resultB = df.withColumn(“r”, expr(“if(x < 0.5, 1, 0)”)).agg(sum($”r”))

resultA.collect() // takes 56s to finishresultB.collect() // takes 30s to finish

发现其在spark旧版本中 IF 比 CaseWhen 要快很多 (30秒 vs 56秒)

虽然没有为Spark贡献成,但是也了解到了Spark 3.0的一些细节优化已经可以解决现在的一些实际问题了,Spark 3.0.1 值得期待应用到产品中!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196875.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 22、Windows10下局域网的两台电脑间传输文件

    22、Windows10下局域网的两台电脑间传输文件一、说明局域网内两台电脑传输文件使用windows自带的文件共享机制即可,不需要找专门的文件传输软件,下面来介绍使用方法。二、步骤1、控制面板2、网络和Internet3、网络和共享中心4、记住网络类型并点击更改高级共享设置5、根据对应的网络类型,在其下选择启用网络发现6、设置所有网络如下7、随便找一个文件夹设置为共享,这里在桌面新建一个名为“共享”的文件夹作文测试8、右击->属性->共享9、在其它电脑上访问自己的的文件夹,假设共享文件夹所在主机IP

    2022年5月4日
    339
  • SP网站SelectSql和searchSql的区别

    SP网站SelectSql和searchSql的区别新入行小白,如有不足请多指教。SP网站进行二次开发,需要对VS开发的页面内的自定义列表行进行删除,需求是用户或者项目经理只能查到并且删除自己的列表。最终发现将源码searchSql改为SelectSql,页面成功显示。此代码中searchSql代表显示所有信息,SelectSql显示特定信息。修改别人的代码真头大。

    2022年6月25日
    24
  • 星愿浏览器有什么优点_星愿浏览器插件

    星愿浏览器有什么优点_星愿浏览器插件目的:想基于浏览器进程抓包,但是想获得噪声相对小的数据,则找相对ChromeGoogle等主流browser更简单的浏览器;想使用Google的某个扩展程序,所以找基于Chrome内核的浏览器所以,我要找基于Chrome内核的简单浏览器最后找到了这几个符合条件的浏览器:星愿、百分cent、Vival、Brave星愿优点:星愿的主页面具有相当的自主性,可以自由拖动添加图标和更换背景、搜索框等。其主页有个搜索漫画的功能,好像在看漫画这一块做了一些页面优化。缺点:只能在它提供的星愿商店里下扩.

    2025年6月11日
    0
  • python如何多行输出_python换行输出 Python里具体怎么用\n换行输出一个数字?[通俗易懂]

    python里如何把每打印10个数就换行的实现print(“每输出十个数字换行,共计输出100个:”)fornuminrange(1,100):#循环一百次print(“%3d”%num,end=””)#不换行输出if(num%10==0):print(“”)#换行输出人的一生要有多艰难,多坎坷而又要多幸运,多凑巧,才能遇到一个绊住自己心的人。如何用python将内…

    2022年4月10日
    88
  • nrm介绍_nr和nmn

    nrm介绍_nr和nmnnrm说明npm服务器是在国外的,所以下载速度会比较慢,所以我们可以设置npm,让其下载包的时候,从国内的服务器上进行下载。设置npm让其从国内服务器下载,需要用到一个工具,这个工具就是nrm安装npminstallnrm-g使用1.查看可用的服务器列表nrmls2.查看当前正在使用的服务器nrmcurrent3.切换到指定的服务器…

    2022年10月24日
    0
  • 杜教筛 以及积性函数的前世今生 –算法竞赛专题解析(4)「建议收藏」

    杜教筛 以及积性函数的前世今生 –算法竞赛专题解析(4)「建议收藏」最全面的杜教筛讲解、最易懂的杜教筛复杂度证明、杜教筛公式、杜教筛模板。

    2022年7月21日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号