2017-10-19 4 views
-1

Ich wurde eine Abfrage zum Ausführen (unten), wo in der Anwendung, die ich erstellen, das von Datum kann zur Laufzeit geändert werden gegeben. Also, wenn ich ein Startdatum von '1/1/2010' starte, erhalte ich viel mehr Daten (216620 Zeilen zurückgegeben) dann wenn ich ein Datum vor 3 Tagen '10/17/2017 'verwendet habe (1006 Zeilen zurückgegeben), aber diese Abfrage dauert aus irgendeinem Grund extrem lange, und in meiner Anwendung läuft es zeitweise ab.Langsame SQL-Abfrage basierend auf dem Datum

Sollte diese Abfrage irgendwie optimiert werden, oder könnte dies ein Server/Hardware-Problem sein? Ich finde gerade diese seltsame eine Abfrage für die letzten 3 Tage dauert so viel länger als eine Abfrage für Daten mehrere Jahre erstreckt, und leider mal-out in meiner WinForms-Anwendung

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

Haben Sie einen Abfrageplan können wir sehen, um den Flaschenhals zu identifizieren – MarkD

+1

Ich habe meinen Beitrag bearbeitet, um den Abfrageplan aufzustellen. Hoffe, das gibt dir genug Informationen. – Maverick

+1

Nicht sicher, wie groß Ihre Transaction-Tabelle ist, aber die geschachtelte Schleife mit einem Clustered-Index-Scan auf beiden Seiten könnte von mindestens einem, wenn nicht zwei, NCIs in der Transaktionstabelle profitieren. –

Antwort

0

Nun, ich fand ein Möglichkeit, um die Abfrage schneller zu machen, obwohl ich nicht sicher bin, warum es funktioniert. Ich wählte aus der Transaction-Tabelle (492k + ​​Zeilen), die die Abfrage mit dem Problem geändert, am Ende Abfrage von diesem. Ich kann nicht erklären, warum das funktioniert hat, aber es hat die Abfrage schnell gemacht.

1

Meine beste Schätzung ist, dass die ursprüngliche Abfrage die Where-Klausel nicht verwendet, um Zeilen schnell genug zu filtern.

Ich würde versuchen, die Abfrage neu zu schreiben, die WHERE-Klausel für die Haupttabelle in einer Unterabfrage setzen. Die Unterabfrage sollte Priorität haben und eine kleine Teilmenge von Daten zurückgeben; dann werden diese weniger Zeilen zu den anderen Tabellen hinzugefügt und durchlaufen die CASE-Anweisung. Warum das möglicherweise größere Dataset so schnell ausgeführt wird ... Ich bin mir nicht sicher, aber ich weiß, dass SQL Server die Ergebnisse früherer Abfragen zwischenspeichert.

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 
Verwandte Themen