如何优化查询以减少执行时间

时间:2019-10-13 06:05:58

标签: sql sql-server-2008 sql-server-2008-r2

我的查询的order by子句与之间的datetime比较导致执行时间增加,因为我已经为datetime编制了索引

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 个答案:

答案 0 :(得分:1)

您似乎正试图从多个来源(EmployeeMachineLinkAttendanceLog)获取员工的信息。那是对的吗?如果是这样,我认为您只需要清理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个条件分组在一起

在不使用括号的情况下将ORAND混合使用时要小心。否则会导致意外结果并可能导致性能下降。

让我知道是否有帮助。

答案 1 :(得分:0)

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;