如何优化这个查询?执行时间太长

问题描述 投票:0回答:1

以下查询运行大约需要 2 分钟。 我正在处理大型表,但即使在索引之后仍然需要很长时间。 任何建议将不胜感激(执行下面的计划)

DECLARE @FromDate datetime
DECLARE @ToDate datetime
DECLARE @SSNumber int
SET @FromDate = '2023-03-01'
SET @ToDate = '2023-07-01'
SET @SSNumber = -1

DECLARE @CareDates TABLE(CareDate datetime, DOW varchar(20))
DECLARE @curDate datetime
DECLARE @curDOW varchar(20)

SET @curDate = @FromDate

WHILE DATEDIFF(day, @curDate, @ToDate + 1) > 0
BEGIN
     SET @curDOW = DATENAME(dw, @curDate)
     INSERT INTO @CareDates (CareDate, DOW) VALUES (@curDate, @curDOW)

     SET @curDate = DATEADD(day, 1, @curDate)
     PRINT DATEDIFF(day, @curDate, @ToDate)
END;

WITH personal_care AS
(
     SELECT PersonalCareID, SSNumber, ItemCode, CareSchedule, IsCurrent, StartDate
          , DATEADD(DAY, -1, (ISNULL(LEAD(StartDate,1) OVER (
              PARTITION BY SSNumber, ItemCode
              ORDER BY SSNumber, ItemCode, StartDate), '9999-12-31'))) AS EndDate
     FROM HOMEResidentPersonalCare
)

SELECT PC.PersonalCareID, 
    CD.CareDate, 
    CD.DOW, 
    PC.SSNumber, 
    PC.ItemCode, 
    PC.CareSchedule, 
    PC.IsCurrent, 
    PC.StartDate, 
    PC.EndDate, 
    PCS.CareScheduleID, 
    PCS.[Shift], 
    PCS.EmployeeID,
    HRPCP.CareProvidedID, 
    ISNULL(HRPCP.Status,'I') AS CareStatus
FROM @CareDates CD
CROSS JOIN personal_care PC 
INNER JOIN HomeResidentPersonalCareSchedule PCS ON PCS.PersonalCareID = PC.PersonalCareID AND (PCS.DayOfWeek = CD.DOW OR PCS.DayOfWeek = 'All')
LEFT JOIN HomeResidentPersonalCareProvided HRPCP ON HRPCP.CareTypeID = PC.ItemCode AND HRPCP.SSNumber = PC.SSNumber AND HRPCP.[Shift] = PCS.[Shift] AND HRPCP.CareDate = CD.CareDate
WHERE CD.CareDate BETWEEN PC.StartDate AND PC.EndDate
AND (HRPCP.Status IS NULL OR HRPCP.Status <> 'D')

执行计划

尝试对表建立索引、重建索引、重写查询。

sql sql-server
1个回答
0
投票

查询执行耗时 1 分 35 秒。

其中 1 分 33 秒用于查找

HOMEResidentPersonalCareProvided
以及相关的键查找。

enter image description here

下面的索引将大大加快速度

CREATE INDEX IX_HRPCP_Whatever 
ON HOMEResidentPersonalCareProvided (SSNumber,CareTypeID, CareDate , Shift) 
INCLUDE (Status, CareProvidedID)

IX_HRPCP_Optimize1
上的查找运算符需要 1 分 32 秒,并在所有执行中读取
412,338,970
行以返回
404,027
,因为它只在两列
SSNumber, CareTypeID
上查找,并且需要使用残差谓词评估
CareDate

Shift
添加为索引中的键列还允许同时对其进行评估(当前作为键查找中的残差完成)。

最后添加包含列可以覆盖索引,并避免对 do 匹配所有四个条件的 227,664 行进行键查找。

© www.soinside.com 2019 - 2024. All rights reserved.