如果你看过《雷霆穹顶外的疯狂麦克斯》,数据和大数据,那么"……你知道法律:两个人进入,一个人离开……"
小心,他来找你了!-图片来自。
HANA,当然,颠倒了,抱歉,中国移动物联网,破坏了这条定律,使两个(或更多)值退出函数,即使只提供了一个输入值。
等等,什么?
好吧,这个Thunderdome参考是一个巨大的插头,只用来引起你的注意。现在,我似乎有了它,淘客返利软件,让我们进入主题
如果您已经使用SQLScript一段时间了,那么您知道用户定义函数(UDF)。如今,返利app下载,这些自定义项既可以处理标量参数,也可以处理表类型参数,既可以处理函数的输入参数,也可以处理函数的输出参数。
函数的主要目的,就像在其他编程语言中一样,是代码重用,使使用它们的代码更易于理解。通过对命名的一些思考,人们甚至可以为手头的问题构建一种特定于领域的语言。在你的SELECT语句中用
来代替
作为例子。现在,对HANA来说,性能考虑几乎总是主要的考虑因素,因此经常会问一个问题:"使用函数不是对性能有害吗?"
我只能用"使用高级语言不是对性能有害吗?"事实上,与"纯"SQL相比,使用函数很容易损失几微秒和几兆字节的内存。但同样,开发人员的主要目标是(正确地)实现最终为用户提供价值的功能。
因此,我的建议是在有助于提高程序员工作效率和担心性能影响的地方使用函数,而实际上人们可以测量它。
回到这个博客的主题。
我刚才看了一个关于stackoverflow的问题,基本上是这样问的,为什么使用带有多个结果的自定义项似乎会导致执行时间变慢,实际使用的结果越多。
因此类似
的操作所需时间大约是
的四倍,即使我们使用相同的输入参数运行相同的函数。程序员的直觉,至少我和stackoverflow的OP的直觉是,HANA会对提供的输入参数计算一次函数,并使用这一次执行的不同结果。
对查询执行时间的一些测试表明,情况并非如此。一个更深入的分析是为了在这里。
尝试设置
为我的"了解系统,拨弄周围"-尝试我创建了一个非常简单的方案:一个用户帐户表和查询,以找到任何用户帐户将到期的日期。不浪费时间发明play doh数据,我只是简单地运行:
有了它,UDF就很容易构建:
这应该相当于这个纯SQL语句:
看起来不错,我想说。
检查执行时间显示:
在39 ms 67µs(服务器处理时间:37 ms 819µs)内成功执行以42 ms 929µs成功执行(服务器处理时间:41 ms 60µs)在44 ms 13µs内成功执行(服务器处理时间:42 ms 492µs)
在1 ms 191µs内成功执行(服务器处理时间:0 ms 385µs)在1毫秒933微秒内成功执行(服务器处理时间:0毫秒825微秒)在2ms507µs(服务器处理时间:0ms827µs)内成功执行
虽然这是一个很大的差异(30倍),但对于当前问题来说,它实际上是错误的。我们需要看的是只有一个或两个结果的执行之间的差异。
仅使用expiryDate输出运行语句:
在29 ms 443µs内成功执行(服务器处理时间:28 ms 200µs)在30 ms 61µs内成功执行(服务器处理时间:28 ms 610µs)在29毫秒586微秒内成功执行(服务器处理时间:28毫秒131微秒)
在1毫秒917微秒内成功执行(服务器处理时间:0毫秒735微秒)在1毫秒63微秒内成功执行(服务器处理时间:0毫秒308微秒)在2ms864µs(服务器处理时间:0ms742µs)内成功执行
在这里我们确实看到了一个重要的区别:纯SQL运行时保持稳定,而UDF只获取单个结果的速度要快得多。
第一阶段"重现问题"成功完成。
继续分析,我对语句进行了处理想看看当你选择一个不存在的用户时会发生什么:
开枪!
当没有匹配记录时,我们的自定义项会出错。这可能不是我们想要的,所以我们需要在代码中考虑到这一点。在这里,我们可以使用EXIT处理程序来捕获'NO DATA FOUND'SQL错误。
通过此更改,将捕获错误,并且UDF返回空值。这和一个空集不一样,但对于这个案例来说已经足够了,而且比错误要好得多。
追踪的麻烦
分析的下一步应该是实际显示每个结果都执行一次自定义项。
我查看了不同的常见嫌疑犯进行语句分析,非常失望:SQL计划缓存,昂贵的语句跟踪和PlanViz都只显示顶级语句+统计信息。
PlanViz显示一个"行搜索"-Pop作为最终处理节点,其中包含投影列表,但仅此而已。
那么,有什么好方法可以找出函数在语句执行期间是否被多次调用?我不想进行一些低级的追踪,所以我对函数进行了修改:
布丁,校样……圣诞节到了吗?
我将使用一个序列将当前要执行的计数器添加到输出值中。
在纯SQL中,对于每一个输出行,淘客佣金,该序列会被提升一次:
这意味着,如果每个输出参数真的调用一次UDF,那么我们应该看到同一结果行的数字会增加。让我们看看我们得到了什么:
这里我们得到了我们的证明,这个函数实际上执行了两次。
好的……那又怎样?
好吧,到目前为止,我花你的时间和精力解释如何发现HANA没有做我们喜欢的事情。如果这是它的结束,你会理直气壮地问,这是为了什么。
不用担心!好结局在望!
答案在于在SQLScript块中使用UDF。但不是这样:
我们必须加强我们的SQLScript游戏。虽然我们已经避免了愚蠢的SELECT…INTO FROM虚拟工作区,将函数结果赋给变量,但它显然现在调用了函数两次。
相反,我们需要在单个赋值中使用函数。"如何在一次赋值中为多个变量赋值?",你问?