使用函数的SQL Server查询非常慢

Mol*_*och 3 sql t-sql sql-server performance sql-function

这类是从前一个问题开始的:

SQL Server查询超时取决于Where子句

根据where子句,查询运行速度非常慢.我重写了该查询使用CTE并很好地避免了问题,但从未找到答案.

另外一个类似的查询最近被调整为添加另一个字段,突然它的性能从大约需要30秒才能运行并返回10,000行,超过10个小时(并最终返回相同的结果集).今天我开始对这个进行故障排除,发现了一些奇怪的东西.

我一直需要从datetime值中提取日期唯一部分,因此我将逻辑写入函数:

CREATE FUNCTION [dbo].[cDate] ( @pInputDate    DATETIME )
RETURNS DATETIME
BEGIN
        RETURN CAST(CONVERT(VARCHAR(10), @pInputDate, 111) AS DATETIME)
END
GO
Run Code Online (Sandbox Code Playgroud)

我发现在这个新的低效查询中,如果我用查询中的CAST(CONVERT(VARCHAR(10), @pInputDate, 111) AS DATETIME)内联替换了该函数,查询执行的速度从大约10小时降到了不到2秒.我看到估计的执行计划没有区别.顺便说一句,这不是添加的领域.我假设添加其他字段以某种方式导致执行计划改变并放大上述条件.

我的问题是,这是正常的吗?如上所述,我使用重复过程的函数,因为如果你找到一种更有效的方法,它们更容易维护,记忆和更新.我应该为我的功能做些什么来提高他们的表现吗?

Mar*_*ith 6

如果你必须将它封装在一个函数中,请参阅标量函数,内联和性能:一个无聊的帖子的有趣标题

重写如下

CREATE FUNCTION dbo.cDate_Inline
(
    @pInputDate DATETIME
)
RETURNS TABLE
AS
    RETURN
    (
        SELECT DATEADD(day, DATEDIFF(Day, 0, @pInputDate), 0) AS [Date]
    )
Run Code Online (Sandbox Code Playgroud)

然后而不是

SELECT *,
       [dbo].[cDate](modify_date) AS modified
FROM   sys.objects 
Run Code Online (Sandbox Code Playgroud)

使用

SELECT *,
       ca.Date AS modified
FROM   sys.objects
       CROSS APPLY dbo.cDate_Inline(modify_date) ca 
Run Code Online (Sandbox Code Playgroud)

这将由查询优化器内联到计划中.


dja*_*azz 0

我会尝试添加另一个变量来进行声明和返回。对此的思考过程可能是您的转换和转换以改变输入的日期时间可能是瓶颈。情况可能并非如此,但通常如果您在作用域中设置一个新变量,进行调节并将其绑定到该变量并返回该变量,这可能有助于提高速度。不过,我倾向于尽可能远离标量函数,当您开始将它们用于较大的数据集时,它们会出现很多性能问题。只是一个建议,它可能有帮助,也可能没有帮助,但它会隔离对新对象的返回,与输入无关:

CREATE FUNCTION [dbo].[cDate] ( @pInputDate    DATETIME )
RETURNS DATETIME
BEGIN
Declare @Output datetime  = CAST(CONVERT(VARCHAR(10), @pInputDate, 111) AS DATETIME)  -- 2008 method and newer

Declare @Output datetime;

Select @Output  = CAST(CONVERT(VARCHAR(10), @pInputDate, 111) AS DATETIME)  -- 2005 and prior method 


return @Output
END
GO
Run Code Online (Sandbox Code Playgroud)