Sql 使用DATEDIFF函数进行无法解释的性能下降

Sql 使用DATEDIFF函数进行无法解释的性能下降,sql,sql-server,performance,Sql,Sql Server,Performance,我对SQL Server中的表值函数有一个奇怪的问题,请参见下面的代码。当我注释掉CONVERTINT,DATEDIFF。。。在函数行中,则结果几乎是瞬时的。当我取消注释它时,它在2018-02-28日期的运行速度有点慢~7秒,在2018-03-31日期的运行速度非常慢,超过一分钟 qryLMPDATE返回一行的表。是什么导致了这个问题?一种想法是,lmpdate等于2018-02-28的valdate,但2018-03-31的lmpdate与valdate不同。因此,可能查询处理器计算值的效率

我对SQL Server中的表值函数有一个奇怪的问题,请参见下面的代码。当我注释掉CONVERTINT,DATEDIFF。。。在函数行中,则结果几乎是瞬时的。当我取消注释它时,它在2018-02-28日期的运行速度有点慢~7秒,在2018-03-31日期的运行速度非常慢,超过一分钟

qryLMPDATE返回一行的表。是什么导致了这个问题?一种想法是,lmpdate等于2018-02-28的valdate,但2018-03-31的lmpdate与valdate不同。因此,可能查询处理器计算值的效率很低

为了提供进一步的上下文,lmpdate本质上是一个常量。任何帮助都将不胜感激

ALTER FUNCTION [ife].[qryFoo](@valdate DATETIME)
RETURNS TABLE
     RETURN
         SELECT 
             pol.*,
             CONVERT(INT, (DATEDIFF(day, pol.[RESP_PRIM_DOB], ql.lmpdate) / 365)) AS AttainedAge
         FROM
             (ife.tblFIAResvPol AS pol
         LEFT JOIN 
             ife.qryFeatGLWB(@valdate) AS glwb ON (pol.RESP_CONT = glwb.RESFE_CONT)
                                               AND (pol.ValDate = glwb.ValDate))
         LEFT JOIN 
             ife.qryFeatROP(@valdate) AS qrop ON (pol.RESP_CONT = qrop.RESFE_CONT)
                                              AND (pol.ValDate = qrop.ValDate)
         LEFT JOIN 
             ife.qryLMPDATE(@valdate) AS ql ON pol.ValDate = ql.ValDate
         WHERE
             (((pol.ValDate) = @valdate));

SELECT TOP 2000 * 
FROM ife.qryFoo('2018-02-28');  --takes <1 and 7 seconds, resp.

SELECT TOP 2000 * 
FROM ife.qryFoo('2018-03-31'); --takes <1 and >60 seconds, resp.
最新更新

罪犯是IFE.qryLMPDATE。将函数修改为使用max而不是top 1后,性能恢复正常。如果有人能找到对此的解释,我会把你的答案标记为被接受的答案

旧代码:

ALTER FUNCTION [IFE].[qryLMPDATE](@valdate DATE)
RETURNS TABLE
AS
     RETURN
(
    SELECT TOP 1 @valdate AS valdate,
                 marketdate AS lmpdate
    FROM ife.tblfiaoptionvalue
    WHERE DATEDIFF(day, MarketDate, @valdate) <= 4
);
新代码:

ALTER FUNCTION [IFE].[qryLMPDATE](@valdate DATE)
RETURNS TABLE
AS
     RETURN
(
    SELECT @valdate AS valdate,
           max(marketdate) AS lmpdate
    FROM ife.tblfiaoptionvalue
    WHERE DATEDIFF(day, MarketDate, @valdate) <= 4
);

看看这个计划,这似乎是因为您在[精算师DW].[IFE].[tblFIAResvFeat]上得到了一个表扫描,我怀疑在IFE.qryLMPDATE函数中会查询到这个表。我怀疑你在[ValDate]上没有索引。基本上,您的查询正在扫描整个表,查找[ValDate]='2018-03-31 00:00:00.000'的值,可以使用索引搜索来加快搜索速度。表越大,所需时间越长,等等。这将占用95%的查询成本。。。因此,我将从添加一些索引和重新测试开始

返回多少行?此外,当DATEDIFF的结果已经是INT时,您将其转换为INT,因此是重复的。你能。最后,我会刷新计划缓存,或者在最后使用OPTIONRECOMPILE,以确保它不会因为使用一个计划而加快速度。i、 因此,你可以真正地将缓慢归功于DateDiffare,在没有订单的情况下使用TOP。只是确保你不在乎返回了2000个结果,总共返回了大约20000行。我在上面的计划中添加了一个链接。深入研究后,我意识到这不是转换或日期差异的直接结果。如果我包括lmpdate,它会变慢,但如果我排除它,它会恢复正常。谢谢。实际上,IFE.qryLMPDATE函数只扫描IFE.tblFIAOptionValue。但你是对的,那张表上也没有索引。我可能会尝试添加索引,和/或将lmpdate存储在表中。再次感谢,谢谢。我添加了一个索引,现在正在处理ife.qryLMPDATE的代码。从我最初的结果来看,ife.qryLMPDATE中的前1条语句似乎引起了一个奇怪的问题。但我明天会继续测试。那份声明中有命令吗?这肯定会伤害它。这些功能也是必需的吗?不,没有订单。谢谢你的帮助;我发现根本原因涉及ife.qryLMPDATE函数中的前1条语句。我更新了我的问题来解释我的发现。
ALTER FUNCTION [IFE].[qryLMPDATE](@valdate DATE)
RETURNS TABLE
AS
     RETURN
(
    SELECT @valdate AS valdate,
           max(marketdate) AS lmpdate
    FROM ife.tblfiaoptionvalue
    WHERE DATEDIFF(day, MarketDate, @valdate) <= 4
);