7

这种继承自上一个问题:

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

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

另一个类似的查询最近被调整以添加另一个字段,突然它的性能从运行大约 30 秒并返回 10,000 行下降到需要 10 多个小时(最终返回相同的结果集)。今天我开始解决这个问题,发现了一些奇怪的东西。

我经常需要从日期时间值中仅提取日期部分,因此我将逻辑写入了一个函数:

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

我在这个新的、低效的查询中发现,如果我用查询中的CAST(CONVERT(VARCHAR(10), @pInputDate, 111) AS DATETIME)内联函数替换该函数,查询执行的速度会从大约 10 小时下降到不到 2 秒。我看不出估计的执行计划有什么不同。顺便说一句,这不是添加的字段。我假设添加另一个字段以某种方式导致执行计划发生变化并放大了上述情况。

我的问题是,这正常吗?如上所述,我将函数用于重复过程,因为如果你找到一种更有效的做事方式,它们更容易维护、记忆和更新。我应该对我的功能做些什么来提高它们的性能吗?

4

2 回答 2

8

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

改写如下

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

然后代替

SELECT *,
       [dbo].[cDate](modify_date) AS modified
FROM   sys.objects 

利用

SELECT *,
       ca.Date AS modified
FROM   sys.objects
       CROSS APPLY dbo.cDate_Inline(modify_date) ca 

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

于 2015-08-23T18:55:01.357 回答
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
于 2012-12-19T19:19:09.667 回答