我有以下查询,我直接在我的Code&把它放在数据表中。问题是执行此查询需要10多分钟。花费时间的主要部分是NON EXISTS
。
SELECT
[t0].[PayrollEmployeeId],
[t0].[InOutDate],
[t0].[InOutFlag],
[t0].[InOutTime]
FROM [dbo].[MachineLog] AS [t0]
WHERE
([t0].[CompanyId] = 1)
AND ([t0].[InOutDate] >= '2016-12-13')
AND ([t0].[InOutDate] <= '2016-12-14')
AND
( NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[TO_Entry] AS [t1]
WHERE
([t1].[EmployeeId] = [t0].[PayrollEmployeeId])
AND ([t1]. [CompanyId] = 1)
AND ([t0].[PayrollEmployeeId] = [t1].[EmployeeId])
AND (([t0].[InOutDate]) = [t1].[Entry_Date])
AND ([t1].[Entry_Method] = 'M')
))
)
ORDER BY
[t0].[PayrollEmployeeId], [t0].[InOutDate]
有什么办法可以优化这个查询吗?为此做了什么工作。这花费了太多时间。
答案 0 :(得分:2)
似乎您可以将NOT EXISTS转换为LEFT JOIN查询,第二个表返回NULL值
请检查以下SELECT并根据需要进行修改以满足您的要求
SELECT
[t0].[PayrollEmployeeId], [t0].[InOutDate], [t0].[InOutFlag], [t0].[InOutTime]
FROM [dbo].[MachineLog] AS [t0]
LEFT JOIN [dbo].[TO_Entry] AS [t1]
ON [t1].[EmployeeId] = [t0].[PayrollEmployeeId]
AND [t0].[PayrollEmployeeId] = [t1].[EmployeeId]
AND [t0].[InOutDate] = [t1].[Entry_Date]
AND [t1]. [CompanyId] = 1
AND [t1].[Entry_Method] = 'M'
WHERE
([t0].[CompanyId] = 1)
AND ([t0].[InOutDate] >= '2016-12-13')
AND ([t0].[InOutDate] <= '2016-12-14')
AND [t1].[EmployeeId] IS NULL
ORDER BY
[t0].[PayrollEmployeeId], [t0].[InOutDate]
答案 1 :(得分:2)
您将意识到查询的执行计划中有一条信息性消息
通知缺少集群索引,执行时间为30%
似乎交易数据是基于某些日期字段(如进入时间)而发生的。 特别是在您的情况下,日期字段是聚簇索引的强大候选者。您可以在Entry_Date列上创建索引 我猜你已经在InOutDate上有一些索引了 您也可以尝试索引此字段