Как оптимизировать запрос, чтобы сократить время выполнения - PullRequest
0 голосов
/ 13 октября 2019

Порядок в моем запросе по сравнению с предложением и датой и временем приводит к увеличению времени выполнения, где, как я уже проиндексировал, дата и время

SELECT TOP(1) 
    @PeriodStart = DATEADD(SECOND, 1, dbo.tbl_WPT_AttendanceLog.ATDateTime) 
FROM         
    dbo.tbl_WPT_EmployeeMachineLink 
INNER JOIN
    dbo.tbl_WPT_Machine ON dbo.tbl_WPT_EmployeeMachineLink.FK_tbl_WPT_Machine_ID = dbo.tbl_WPT_Machine.ID 
RIGHT OUTER JOIN
    dbo.tbl_WPT_AttendanceLog ON dbo.tbl_WPT_EmployeeMachineLink.FK_tbl_WPT_Machine_ID = dbo.tbl_WPT_AttendanceLog.FK_tbl_WPT_Machine_ID 
                              AND dbo.tbl_WPT_EmployeeMachineLink.MachineEnrollmentNo = dbo.tbl_WPT_AttendanceLog.ATEnrollmentNo
WHERE     
    (dbo.tbl_WPT_EmployeeMachineLink.FK_tbl_WPT_Employee_ID = @EmpID) 
    AND (dbo.tbl_WPT_AttendanceLog.ATDateTime BETWEEN @ShiftEndPreviousInstance AND @ShiftStart) 
    AND dbo.tbl_WPT_AttendanceLog.ATInOutMode in (1,2,5)
    OR (dbo.tbl_WPT_AttendanceLog.ATDateTime BETWEEN @ShiftEndPreviousInstance AND @ShiftStart)
    AND (dbo.tbl_WPT_AttendanceLog.FK_tbl_WPT_Employee_ID = @EmpID) 
    AND dbo.tbl_WPT_AttendanceLog.ATInOutMode in (1,2,5)
ORDER BY
    dbo.tbl_WPT_AttendanceLog.ATDateTime DESC

Ответы [ 2 ]

1 голос
/ 13 октября 2019

Похоже, вы пытаетесь получить информацию о сотруднике из нескольких источников (EmployeeMachineLink и AttendanceLog). Это правильно? Если это так, я думаю, вам просто нужно очистить логику предложения WHERE:

SELECT TOP(1) 
  @PeriodStart = DATEADD(SECOND, 1, dbo.tbl_WPT_AttendanceLog.ATDateTime) 
FROM dbo.tbl_WPT_EmployeeMachineLink eml
INNER JOIN dbo.tbl_WPT_Machine ON eml.FK_tbl_WPT_Machine_ID = dbo.tbl_WPT_Machine.ID 
RIGHT OUTER JOIN dbo.tbl_WPT_AttendanceLog ON eml.FK_tbl_WPT_Machine_ID = dbo.tbl_WPT_AttendanceLog.FK_tbl_WPT_Machine_ID 
  AND eml.MachineEnrollmentNo = dbo.tbl_WPT_AttendanceLog.ATEnrollmentNo
WHERE (
  eml.FK_tbl_WPT_Employee_ID = @EmpID OR
  dbo.tbl_WPT_AttendanceLog.FK_tbl_WPT_Employee_ID = @EmpID
) 
AND (dbo.tbl_WPT_AttendanceLog.ATDateTime BETWEEN @ShiftEndPreviousInstance AND @ShiftStart)
AND dbo.tbl_WPT_AttendanceLog.ATInOutMode IN (1,2,5)
ORDER BY dbo.tbl_WPT_AttendanceLog.ATDateTime DESC

Изменения
- добавлен псевдоним таблицы eml для удобства чтения
-удалена дублирующая ссылка на dbo.tbl_WPT_AttendanceLog.ATInOutMode IN (1,2,5)
- удалена дубликат BETWEEN ... AND ... ссылка
- сгруппированы OR условия вместе

Вы должны быть осторожны при смешивании OR с AND без использования скобок,В противном случае это приведет к неожиданным результатам и, возможно, к снижению производительности.

Дайте мне знать, если это поможет.

0 голосов
/ 13 октября 2019
SELECT TOP (1)
       @PeriodStart = DATEADD(SECOND, 1, dbo.tbl_WPT_AttendanceLog.ATDateTime)
FROM dbo.tbl_WPT_EmployeeMachineLink
    INNER JOIN dbo.tbl_WPT_Machine
        ON dbo.tbl_WPT_EmployeeMachineLink.FK_tbl_WPT_Machine_ID = dbo.tbl_WPT_Machine.ID
    RIGHT OUTER JOIN dbo.tbl_WPT_AttendanceLog
        ON dbo.tbl_WPT_EmployeeMachineLink.FK_tbl_WPT_Machine_ID = dbo.tbl_WPT_AttendanceLog.FK_tbl_WPT_Machine_ID
           AND dbo.tbl_WPT_EmployeeMachineLink.MachineEnrollmentNo = dbo.tbl_WPT_AttendanceLog.ATEnrollmentNo
WHERE dbo.tbl_WPT_AttendanceLog.FK_tbl_WPT_Employee_ID = @EmpID
      AND dbo.tbl_WPT_AttendanceLog.ATInOutMode IN ( 1, 2, 5 )
      AND
      (
          dbo.tbl_WPT_AttendanceLog.ATDateTime
      BETWEEN @ShiftEndPreviousInstance AND @ShiftStart
          OR dbo.tbl_WPT_AttendanceLog.ATDateTime
      BETWEEN @ShiftEndPreviousInstance AND @ShiftStart
      )
ORDER BY dbo.tbl_WPT_AttendanceLog.ATDateTime DESC;
...