where 子句中的 dateadd - 在这种特定情况下如何避免完全扫描?

Mar*_*lli 5 index sql-server execution-plan sql-server-2016 query-performance

我有以下查询:

SELECT      u.userId,
            app.applicationId
FROM        app.application                 AS app
INNER JOIN  app.applicant                   AS ap   
            ON ap.applicantId = app.applicantId
INNER JOIN  usr.[user]                      AS u    
            ON u.userId = ap.userId
LEFT JOIN   msg.emailTemplateSent           AS t    
            ON t.toUserId = u.userId 
           AND t.emailTemplateName = 'v4_before_sixWeek_latestFlight_reminder'

WHERE       Convert(Date, GETUTCDATE())  = 
            DATEADD(week,-6,Convert(Date, app.flightDateLatest ))

AND         t.emailEventId IS NULL

ORDER BY    app.applicationId ASC
Run Code Online (Sandbox Code Playgroud)

请再次注意where子句的第一行:

Convert(Date, GETUTCDATE())  = DATEADD(week,-6,Convert(Date, app.flightDateLatest ))
Run Code Online (Sandbox Code Playgroud)

我可以以可以使用我的索引的方式更改此设置吗?索引实际上被使用了,但它是一个完整的扫描。

在此输入图像描述

也可以在这里看到:

在此输入图像描述

这是我的索引定义:

USE [APCore];
CREATE NONCLUSTERED INDEX i_flightDateLatest  
ON [app].[application] ( flightDateLatest  ASC  )  
INCLUDE ( [applicantId] , [applicationId] , [programID])  
WITH (  PAD_INDEX = OFF, 
        FILLFACTOR = 100  , 
        SORT_IN_TEMPDB = OFF , 
        ONLINE = OFF, 
--DROP_EXISTING = ON, 
        IGNORE_DUP_KEY = OFF, 
       STATISTICS_NORECOMPUTE = OFF, 
       DATA_COMPRESSION=PAGE, 
       ALLOW_ROW_LOCKS = ON, 
       ALLOW_PAGE_LOCKS = ON ) 
ON [NONCLUSTERED_INDEXES] 
Run Code Online (Sandbox Code Playgroud)

这是完整的执行计划

flightDateLatest不幸的是,我无法更改从日期时间调用的列以避免转换

除了创建计算列或更改架构之外,还有其他方法可以避免在这种情况下读取全表\索引扫描吗?

更新:

在接受答案后,相应地更改了查询,现在索引用于查找操作,如下图所示。

请注意原始查询成本的 94% 是改进后查询的 6%:

在此输入图像描述

Sab*_*n B 9

您可以在 getutc 中添加 6 周...
然后测试该特定日期 (flightDateLatest) 是否大于或等于DATEADD(week,6,Convert(Date, GETUTCDATE()))
或小于第二天DATEADD(DAY,1,DATEADD(week,6,Convert(Date, GETUTCDATE())))

SELECT
*
FROM
(
    SELECT CAST('20220511 15:14:52.050' AS DATETIME) as flightDateLatest union all
    SELECT CAST('20220512' AS DATETIME) 
) as app
WHERE   
    app.flightDateLatest >= DATEADD(week,6,Convert(Date, GETUTCDATE()))
    AND 
    app.flightDateLatest < DATEADD(DAY,1,DATEADD(week,6,Convert(Date, GETUTCDATE())))
Run Code Online (Sandbox Code Playgroud)

与输出:

flightDateLatest
2022-05-11 15:14:52.050
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

1251 次

最近记录:

3 年,5 月 前