sql-server - 在 View 中使用调用 GETDATE() 的函数是否始终比直接使用 GETDATE() 提供更差的性能?

标签 sql-server performance tsql user-defined-functions getdate

我有一个函数可以获取过去/ future 周 @X 周的星期一。我将它与本网站上的其他代码结合在一起。我相信它是这样的:

CREATE FUNCTION [FOO]
    (@X INT)
RETURNS DATE
AS
BEGIN
    RETURN DATEADD(WEEK, @X, DATEADD(d, -((DATEPART(DW, GETDATE()))
END

我最近发现,如果我在一个 View 中调用这个函数,那么我得到的性能比我复制和粘贴上面的代码要差得多。换句话说,我发现直接使用 CAST(DATEADD(WEEK, [X VALUE HERE], DATEADD(d, -((DATEPART(DW, GETDATE())) AS DATE) 会很远比使用 FOO([X VALUE HERE]) 性能更高。

如果要信任事件监视器,那么当您使用用户定义的函数时就好像忘记了 GETDATE() 的值;当我尝试查询使用它的任何 View 时,我发现我的用户定义函数被调用了很多次。

此行为是否有任何已知原因?就好像用 GETDATE() 做函数总是一个坏主意。 This question有很多暗示,但这不是直接的答案。

我已经检查了任何类型的任何类型不匹配。空无一人。 @@VERSION 报告我使用的是 2016 版本。

最佳答案

这篇 SqlServer 2019 文章对此进行了全部解释:https://learn.microsoft.com/en-us/sql/relational-databases/user-defined-functions/scalar-udf-inlining?view=sql-server-ver15 .正如@JeroenMostert 所解释的那样,除非您拥有 v2019 或更高版本并且可以满足所有要求,否则标量 UDF 往往会在性能方面表现不佳。

在 v2019 之前解决此问题的唯一方法是改为将其更改为内联表值函数 (iTVF)。它们使用以下语法:

-- Transact-SQL Inline Table-Valued Function Syntax
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type
    [ = default ] [ READONLY ] }
    [ ,...n ]
  ]
)
RETURNS TABLE
    [ WITH <function_option> [ ,...n ] ]
    [ AS ]
    RETURN [ ( ] select_stmt [ ) ]
[ ; ]

然后必须使用 JOINAPPLY 或子查询来调用。

关于sql-server - 在 View 中使用调用 GETDATE() 的函数是否始终比直接使用 GETDATE() 提供更差的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72788519/

相关文章:

sql-server - select 1 和 select * 哪个更好来检查记录的存在?

c++ - 将列表从 python 传递到 C++ vector 时如何加速 Boost::Python::Extract

sql-server - 使用不同的增量值更新多个记录

sql-server - SQL Server 中是否可以使用正则表达式检查约束

c# - 需要将一列分成两列

c - 仅使用常量移位模拟可变位移位?

sql-server - 如何向现有 SQL 表添加一列

sql-server - SQL Rank 未按预期工作

sql - 检查给定的月份+日期是否存在于包含月份+日期范围的数据中

java - 适当的 Tomcat 5.5 启动参数来调整 JVM 以满足极高的需求、大堆 Web 应用程序?