在我的存储过程中,我有一个临时表,它是为了提高性能而创建的 .
使用存储过程中的实际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个参数进入,金额输出 .
一块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函数?
谢谢你的帮助 .
1 回答
您要求的是SQL Server 2019(CTP2.1及更高版本)中最近公布的名为“Scalar UDF Inlining”的功能的焦点 . 此功能通过自动将UDF的逻辑嵌入(或内联)到调用查询中来工作 . 你可以试试免费下载它 .
如果您想了解它在幕后的工作原理,可以在最近的研究论文“Froid: Optimization of Imperative programs in a Relational Database”中找到详细信息 . 该文描述了一种将整个UDF表达为SQL的系统方法,您可以使用它 . Scalar UDF内联功能基于Froid,在许多情况下可以带来巨大的性能提升 .
[披露:我是Froid论文的合着者]