在我的存储过程中,我有一个临时表,它是为了提高性能而创建的。
对于存储过程中的实际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我如何在我的存储过程select中插入这个UDF代码?或者,我可以用什么方法使其成为UDF_table函数?
谢谢你的帮助。
发布于 2018-12-11 09:46:03
您所要求的正是SQL Server2019 (CTP2.1及更高版本)中最近宣布的一个名为"Scalar UDF Inlining“的特性的焦点。此功能的工作方式是将UDF的逻辑自动嵌入(或内联)到调用查询中。你可以通过免费下载来尝试一下。
如果你想知道它在幕后是如何工作的,可以在最近的研究论文“Froid: Optimization of Imperative programs in a Relational Database”中找到详细信息。这篇文章描述了一种系统的方法,将整个UDF表示为SQL,您可以使用它。Scalar UDF内联功能基于Froid,在许多情况下可以带来巨大的性能提升。
披露:我是Froid论文的合著者
https://stackoverflow.com/questions/53705571
复制相似问题