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 值得期待应用到产品中!

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(2)


相关推荐

  • 机器学习–朴素贝叶斯模型原理

    机器学习–朴素贝叶斯模型原理朴素贝叶斯中的朴素是指特征条件独立假设,贝叶斯是指贝叶斯定理, 我们从贝叶斯定理开始说起吧.1.贝叶斯定理贝叶斯定理是用来描述两个条件概率之间的关系1).什么是条件概率?如果有

  • idea 查看jsp是否被引用_idea 运行JSP后显示源代码是什么情况

    idea 查看jsp是否被引用_idea 运行JSP后显示源代码是什么情况该楼层疑似违规已被系统折叠隐藏此楼查看此楼没加struts的jar包时可以用,加上jar包后就不能用了。tomcat好像有一个报错信息”C:\ProgramFiles\Java\apache-tomcat-7.0.54\bin\catalina.bat”run[2014-09-1909:05:12,773]Artifactdemo:warexploded:Serverisnot…

    2022年10月21日
  • pattern 正则_JAVA 正则表达式

    pattern 正则_JAVA 正则表达式1.组(Group)组是正则表达式的一个子集,每个组都有一个编号,通过从左到右计算左括号来进行编号。正则表达式“((A)(B©))”有4个组:((A)(B©))(A)(B©)©组0表示整个正则表达式,除组0外每一个组都被一对括号括住,如果一个正则表达式里面没有括号,则它只有组0即整个表达式。下面是组号的示例程序:Patternp=Pattern.compile(“([0-9]+)([^0-9]+)”);Matcherm1=p.matcher(“namejack,age18

  • Java走向中国

    Java走向中国             今天,工作之余浏览sun网站的文档中心,惊喜地看到j2se5.0viewchinese!!! 毫不犹豫,先点之而后快。 进入网页: http://gceclub.sun.com.cn/chinese_java_docs.html         虽然只有一个包被翻译了,但不管怎么说,这是一个好的开始!而且更令人高兴的是,这次,j2se5.0版

  • C++ 获取窗口句柄

    C++ 获取窗口句柄1、使用FindWindow函数获取窗口句柄示例:使用FindWindow函数获取窗口句柄,然后获得窗口大小和标题,并且移动窗口到指定位置。[html] viewplaincopy#include Windows.h>  #include stdio.h>  #include string.h>  #include iostre

  • activity工作流引擎

    activity工作流引擎工作流activity引擎入门案例1、工作流是什么?简单来说工作流就是将一条信息根据角色、分工、条件不同进行固定的向上传递,数据是按照固定的流向进行传输,一级一级传递下去,这种场景在OA,CRM/ERP中应用的比较多。通常这种操作自己本身也可以通过逻辑来实现,但是复杂度很高。而且不方便维护。所以通常都采用第三方引擎框架来实现,出了引擎本身简化了操作以外。更重要的是维护起来很方便。2、…

发表回复

您的电子邮箱地址不会被公开。

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