我的查询的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
答案 0 :(得分:1)
您似乎正试图从多个来源(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
混合使用时要小心。否则会导致意外结果并可能导致性能下降。
让我知道是否有帮助。
答案 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;