2016-12-21 50 views
0

我有以下查詢,我直接在我的代碼&中執行將其置於數據表中。問題是執行此查詢需要超過10分鐘的時間。需要時間的主要部分是NON EXISTSSQL查詢不存在優化

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

請修復你的格式。 –

+0

寫入存在的部分作爲連接並再次檢查性能 – ManOnAMission

+0

您是否也請分享執行計劃?這將指導我們的性能修復事實上 – Eralper

回答

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] 
+0

當我運行這個查詢時,它在1秒內執行。但是,舊查詢和新查詢之間的結果總計數的唯一區別是1條記錄。 舊查詢需要10分鐘以上 - 總數 - 9109 。新查詢需要1秒 - 總數 - 9110 – Anup

+0

實際上,您可能需要在WHERE子句中添加附加條件。我們只在LEFT JOIN條件中添加了t1.EmployeeId IS NULL。順便說一句,我剛剛意識到我們有兩次「[t1]。[EmployeeId] = [t0]。[PayrollEmployeeId]」在LEFT JOIN – Eralper

+0

我也注意到了一件事。當我運行我的舊查詢日期範圍較大,例如2016-12-01至2016-12-20。然後查詢運行時間不到一秒鐘。只有當我取小範圍時,創建索引後,現在需要超過40秒。 – Anup

2

您將會意識到,您的查詢在執行計劃上有一條信息性消息

它通知在執行時間上有一個缺失聚簇索引,效果爲30%

似乎事務數據是基於某些日期字段(如Entry Time)發生的。 日期字段,尤其是您的案例的日期字段是聚簇索引的強候選字段。你可以在Entry_Date列創建一個索引 我想你已經在InOutDate上有一些索引 你也可以嘗試索引這個字段以及

+0

由於我在'Entry_Date'上創建了索引,現在只需要30秒。 – Anup