从多列返回值的 SQL 函数
Posted
技术标签:
【中文标题】从多列返回值的 SQL 函数【英文标题】:SQL Function to return value from multiple columns 【发布时间】:2020-07-13 10:03:42 【问题描述】:我一直在开发一些存储过程,并且我一直在重复部分代码,这些代码基于其他一些列派生列。因此,我没有将这段代码从一个存储过程复制到另一个存储过程,而是考虑使用一个函数来获取输入列并生成输出列。
基本上,函数如下:
SELECT columnA, columnB, columnC, myFunction(columnA, columnB) as columnD FROM myTable
我们可以看到,这个函数将A列和B列作为输入,然后返回D列。
但是,根据一些研究,使用这样的 UDF(用户定义)函数时似乎存在一些性能问题。真的吗?处理这种情况的最佳方法是什么?
谢谢你们。
【问题讨论】:
信息如此之少,无法给出建议。这将取决于你真正需要什么。即使是最小的函数也会自然地产生一些性能问题(即:upper(myColumnA)),但值得对其进行优化以获得可能以纳秒为单位的时间是值得商榷的。如果您非常担心,请将其留给前端。 我最初在下面发布了我的答案,但没有明确说明用内联表值函数替换 scalar 用户定义函数(形式为create function foo() returns int as ...
以提高性能。同样的论点仍然适用不过,所以我编辑了答案以使其更加明确。您可以使用内联 TVF 返回“标量”值,交叉应用它,而不会遇到在选择中使用真正的标量 UDF 的性能问题。跨度>
【参考方案1】:
标量函数和多语句表值用户定义函数可能会导致性能问题,因为它们会将基于集合的操作隐式转换为基于游标的操作。
但是,内联表值用户定义函数不会遇到此问题。他们很快。
不同之处在于您如何声明函数,以及代码在其中的样子。多语句函数按照它在锡上所说的做 - 它允许您拥有多个语句。像这样:
create function slow() returns @t table(j int, k int) as
begin
declare @j int = 1; -- statement 1
declare @k int = 2; -- statement 2
insert @t values (@j, @k); -- statement 3
return; -- statement 4
end
内联表值函数不返回填充在函数内部的命名表。它返回一个选择语句:
create function quick() returns table as
return
(
select j = 1, k = 2
);
内联表值函数可以“内联”到外部选择语句中,方式与视图大致相同。当然,区别在于 UDF 可以接受参数,而视图不能。
您还必须以不同的方式使用它们。使用交叉应用:
select t.columnA, t.columnB, u.j, u.k
from MyTable t
cross apply quick(t.columnA, t.columnB) u
如果不清楚 - 是的,在您的情况下,您只想要一个“标量”值,但这只是一个返回单列和单行的表值函数。因此,与其编写标量函数,不如编写一个内联表值函数来完成相同的工作,然后cross apply
它。
【讨论】:
正是我想澄清的!非常感谢@allmhuran @Kelvin 另一个注意事项 - 在最近 (2019) 版本的 SQL 中,标量函数也可以内联 - 在某些条件下。不过,它现在看起来确实有点马车。 Documentation以上是关于从多列返回值的 SQL 函数的主要内容,如果未能解决你的问题,请参考以下文章