现在可以安全使用T-SQL中的UDF吗?

问题描述 投票:0回答:1

[14年以来,我一直以宣誓的引用为生:“永远不要在受影响的一两行以上使用UDF。”

我将通过一个非常基本的示例来与我的团队分享UDF的糟糕程度:

/*
CREATE FUNCTION dbo.Test (@Numerator Float, @Denominator Float)
RETURNS Float AS
BEGIN
DECLARE @Return Float;
SET @Return = @Numerator / NullIf(@Denominator,0);
RETURN @Return
END
GO
*/
----------------------------------------------------------------------
SELECT rn / NullIf(3.00,0)
FROM
       (
       SELECT TOP 1000000 rn = Convert(Float,ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
       FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
       ORDER BY s1.[object_id]
       ) tbl;
----------------------------------------------------------------------
SELECT dbo.Test (rn,3.00)
FROM
       (
       SELECT TOP 1000000 rn = Convert(Float,ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
       FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
       ORDER BY s1.[object_id]
       ) tbl;
----------------------------------------------------------------------
--DROP FUNCTION dbo.Test;
GO

但是,当我准备进行表演时,运行第一个程序块和第二个程序块所需的时间几乎完全相同,大约8秒。我记得进行了一个非常类似的实验, 6年前,并且注意到执行时间成指数增长。

UDF现在可以安全使用了吗?发生了什么变化?

sql-server tsql user-defined-functions sql-execution-plan
1个回答
1
投票

如果用“安全”来表示“不是慢和/或低效”,那么答案是:Inline =好,而不是inline =不好。*不要为此而工作,只需询问Microsoft:

https://docs.microsoft.com/en-us/sql/relational-databases/user-defined-functions/scalar-udf-inlining?view=sql-server-ver15#performance-of-scalar-udfs

T-SQL内联函数can写得不好时会很慢,但是T-SQL标量UDF和多语句表值函数(mTVF)肯定会破坏性能。

这里有几个链接,我在其中进行了一些测试,或者对此进行了更详细的讨论。

When would you use a table-valued function?

https://www.sqlservercentral.com/forums/topic/inline-vs-multi-statement-table-valued-function-temp-tables-vs-ctes#post-1784973

现在,SQL Server 2019引入了内联标量和mTVF。这些比他们的前辈更好,但并不完美。例如,将标量UDF用作CHECK约束或计算列将迫使优化器选择带有引用该表的查询的串行计划(插入/更新/删除和选择)。即使在查询中未调用引用该函数的列也是如此。在SQL 2019中仍然如此。

© www.soinside.com 2019 - 2024. All rights reserved.