问题
I've been developing a few stored procedure and I have been repeating a portion of codes that derives a column based on a few other columns. So instead of copy this piece of code from one stored procedure to another, I'm thinking of having a function that takes the input columns and produces the output columns.
Basically, the function goes as:
SELECT columnA, columnB, columnC, myFunction(columnA, columnB) as columnD FROM myTable
As we can see, this function will take column A and column B as inputs, then return column D.
However, based on some research, it seems to have some performance issues when using UDF (user-defined) function like this. Is that true? What's the best way to handle this situation?
Thank you guys.
回答1:
Scalar functions and multi statement table valued user defined functions can cause performance issues, because they implicitly turn your set based operation into a cursor based operation.
However, inline table valued user defined functions do not suffer from this problem. They're fast.
The difference is how you declare the fuction, and what the code looks like inside them. A multi statement function does what it says on the tin - it lets you have multiple statements. Like this:
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
An inline table valued function does not return a named table which is populated inside the function. It returns a select statement:
create function quick() returns table as
return
(
select j = 1, k = 2
);
The inline table valued function can be "inlined" into the outer select statement, in much the same way as a view. The difference, of course, being that the UDF can take parameters, whereas a view cannot.
You also have to use them differently. Use cross apply:
select t.columnA, t.columnB, u.j, u.k
from MyTable t
cross apply quick(t.columnA, t.columnB) u
In case it's not clear - yes, in your case you only want a "scalar" value back, but that's just a table valued function which returns a single column and a single row. So instead of writing a scalar function, write an inline table valued function that does the same job, and cross apply
it.
来源:https://stackoverflow.com/questions/62873517/sql-function-to-return-value-from-multiple-columns