在存储过程中,我创建了一个临时表来提高性能。
在存储过程中使用实际的select语句时,使用了多个标量UDF,临时表替换了它们:
INSERT INTO #BEDRAGEN
SELECT
DD.ColumnA, DD.ColumnB, DD.ColumnC,
ISNULL(DBO.SIF_get_SalesAmount(DD.ColumnA, DD.ColumnB, DD.ColumnC), 0) AS Totaalbedrag,
FROM
T_InvoiceDetailDosDet as IDD
我的问题是:如果要提高性能,我想用代码替换dbo.SIF_get_SalesAmount
或将标量UDF制成表表。
此UDF中的内容是什么
退还金额。
它读取文件并计算出几件事,然后才得出总数。
该函数有3个参数输入和Amount输出。
UDF片段:
ALTER FUNCTION [dbo].[SIF_get_SalesAmountDosDetail]
(@A VARCHAR(20),
@B VARCHAR(20),
@C VARCHAR(20)
)
RETURNS NUMERIC(12,2)
AS
DECLARE @SalesAmount NUMERIC(12,2)
, @SalesUnitOfAccount TINYINT
, @Unit NCHAR(5)
, @SalesUnit NCHAR(5)
, @TotalUnits NUMERIC(15, 3)
SELECT
@unit = p.Unit,
@SalesUnit = p.SalesUnit,
@SalesUnitOfAccount = dd.SalesUnitOfAccount
FROM
dbo.T_table p
WHERE
p.ColumnA = @A AND p.ColumnB = @B AND p.ColumnC = @C
SELECT @rc = @@ROWCOUNT
IF @rc <> 1
BEGIN
SELECT @SalesAmount = 0
RETURN @SalesAmount
END
IF @SalesUnit = 0
BEGIN
SELECT @SalesUnit = 1
END
-- several calculations follow based on values of @Unit etc.
-- at the end of the UDF:
-- last if then else calculation and then returning the Amount.
IF @SalesUnitOfAccount = 4
BEGIN
SELECT @PricePerDesc = @SalesUnit
SELECT @SalesAmount = CONVERT(numeric(12, 2), round((@CurrPrice * (@TotalSalesUnits / @SalesComputQty)) - @DiscAmount, 2))
END
SELECT @TotalSalesAmount = @TotalSalesAmount + ISNULL(@SalesAmount, 0)
-- Return the result of the function
RETURN @TotalSalesAmount
我可以通过什么方式在存储过程选择中插入此UDF代码?还是我可以用什么方法将其设为UDF_table函数?
感谢您的帮助。
答案 0 :(得分:0)
您所要的恰恰是SQL Server 2019(从CTP2.1起)最近宣布的称为“ Scalar UDF Inlining”的功能的重点。此功能通过自动将UDF的逻辑嵌入(或内联)到调用查询中而起作用。您可以通过免费下载来尝试一下。
如果您想知道它在幕后的工作方式,可以在最近的研究论文“ Froid: Optimization of Imperative programs in a Relational Database”中找到详细信息。该论文描述了一种系统方法,可以将整个UDF表示为SQL,您可以使用它。标量UDF内联功能基于Froid,在许多情况下可以带来巨大的性能提升。
[披露:我是Froid论文的共同作者]