2017-10-19 127 views
-1

我被給了一個查詢來運行(下),在應用程序中,我創建的起始日期可以在運行時更改。因此,如果我運行「1/1/2010」的開始日期,那麼我會檢索更多數據(返回216620行),如果我在3天前'10/17/2017'(1006行返回)使用了日期,但該查詢由於某種原因需要很長時間,並且在我的應用程序中超時。基於日期的慢SQL查詢

該查詢是否應該以某種方式進行優化,或者這可能是服務器/硬件問題?我只是覺得這個奇怪的查詢在過去3天內需要這麼比數據跨越多年了,可惜時間出在我的WinForms應用程序查詢更長

SELECT AC.account_and_parents As Account, 
    TR.IBLoad as [Load ID], 
    LD.load_inboundBOL as [Customer Details], 
    TR.ItemNumber as ITEMNUM, 
    IT.[Description] As[Description], 
    TR.ToPalletID As[Pallet ID], 
    Format(TR.Receivedate, 'MM/dd/yyyy') as Receive_Date, 
    TR.QTY as NETWEIGHT, 
    TR.WeightGross as [Gross Weight], 
    TR.ContainerType, 
    TR.InvenType, 
    TR.Route, 
    tr.ToWarehouse as Warehouse, 
    tr.category as Category, 
    tr.FGatIntake as [FG at Intake], 
    CASE 
    When TR.FGatIntake = 1 
    THEN 
     (SELECT TOP 1 tr.ItemNumber FROM [databaseName].[dbo].[Transaction] TR1 WHERE TR1.ToPalletID = TR.ToPalletID and TransCode = 'FRCPT') 
    END As[Finished Good] 
    FROM [databaseName].[dbo].[Transaction] TR 
    INNER JOIN [databaseName].[dbo].[Item] IT 
    on tr.ItemNumber = IT.ItemNumber 
    INNER JOIN som5.dbo.Loads LD 
    on TR.IBLoad = LD.OID 
    INNER JOIN [SOM5].[dbo].[Accounts] AC 
    on ld.load_Account = AC.OID 

      -- PROBLEM IS HERE. Lots or records (January start) are fast, 
      -- but few records (October start) are *very* slow. 
    WHERE (TransDateTime Between '10/16/2017' and '10/19/2017') 
    and Transcode = 'BRCPT' 
    and ToPalletID not in (Select FromPalletID FROM [SOM5].[dbo].[Transaction] where TransCode = 'UNBRCPT') 
     ORDER BY Receive_Date,[Load ID],[Pallet ID] 

enter image description here

+1

你有一個查詢計劃,我們可以看到識別瓶頸 – MarkD

+1

我編輯我的帖子,把查詢計劃。希望給你足夠的信息。 – Maverick

+1

不知道事務表有多大,但是在其兩側都有聚簇索引掃描的嵌套循環可以從事務處理表上至少有一個(如果不是兩個)NCI受益。 –

回答

0

嗯,我找到了一個以更快的速度查詢,儘管我不確定它爲什麼會起作用。 我從事務表(492k +​​行)中選擇,修改了問題查詢,最後從中查詢。我無法解釋爲什麼這會起作用,但它使查詢變得很快。

1

我最好的猜測是原始查詢不使用Where子句來儘快過濾行。

我會嘗試重寫查詢,將主表的where子句放在子查詢中。子查詢應該有優先權,返回一小部分數據;那麼這些較少的行將連接到其他表並通過CASE語句。至於爲什麼可能更大的數據集執行如此迅速......我不確定,但我確實知道SQL Server緩存來自以前查詢的結果。

SELECT AC.account_and_parents As Account, 
     TR.[Load ID], 
     LD.load_inboundBOL as [Customer Details], 
     TR.ITEMNUM, 
     IT.[Description] As[Description], 
     TR.[Pallet ID], 
     Format(TR.Receivedate, 'MM/dd/yyyy') as Receive_Date, 
     TR.NETWEIGHT, 
     TR.[Gross Weight], 
     TR.ContainerType, 
     TR.InvenType, 
     TR.Route, 
     tr.Warehouse, 
     tr.category as Category, 
     tr.[FG at Intake], 
     CASE 
     When TR.[FG at Intake] = 1 
     THEN (SELECT TOP 1 tr.ItemNumber FROM [databaseName].[dbo].[Transaction] TR1 WHERE TR1.ToPalletID = TR.[Pallet ID] and TransCode = 'FRCPT') 
    END As[Finished Good] 
    FROM (
      SELECT IBLoad as [Load ID], 
       ItemNumber as ITEMNUM, 
       ToPalletID As[Pallet ID], 
       Format(Receivedate, 'MM/dd/yyyy') as Receive_Date, 
       QTY as NETWEIGHT, 
       WeightGross as [Gross Weight], 
       ContainerType, 
       InvenType, 
       Route, 
       ToWarehouse as Warehouse, 
       category as Category, 
       FGatIntake as [FG at Intake] 
      FROM [databaseName].[dbo].[Transaction] 
      WHERE TransDateTime >= '2017-10-16' 
      AND TransDateTime <= '2017-10-19' 
     ) AS TR INNER JOIN [databaseName].[dbo].[Item] IT on tr.ITEMNUM = IT.ItemNumber 
       INNER JOIN som5.dbo.Loads LD on TR.[Load ID] = LD.OID 
       INNER JOIN [SOM5].[dbo].[Accounts] AC on ld.load_Account = AC.OID