2016-12-28 1 views
-1

Wenn ich die folgende Abfrage ausführte dauerte es fast 4 min.Wie schreibe ich eine SQL-Abfrage in einer besseren Weise für die Optimierung?

Dies ist die Abfrage

SELECT 
    transactionsEntry.StoreID StoreID, 
    items.ItemLookupCode ItemLookupCode, 
    SUM(transactionsEntry.Quantity) 
FROM 
    [HQMatajer].[dbo].[TransactionEntry] transactionsEntry 
RIGHT JOIN 
    [HQMatajer].[dbo].[Transaction] transactions ON transactionsEntry.TransactionNumber = transactions.TransactionNumber 
INNER JOIN 
    [HQMatajer].[dbo].[Item] items ON transactionsEntry.ItemID = items.ID 
WHERE 
    YEAR(transactions.Time) = 2015 
    AND MONTH(transactions.Time) = 1 
GROUP BY 
    transactionsEntry.StoreID, items.ItemLookupCode 
ORDER BY 
    items.ItemLookupCode 

TransactionEntry Tabelle 90 Milliarden Datensätze haben, Transaction Tabelle 30 Milliarden Datensätze hat, item Tabelle hat 40 k Datensätze.

Schätzungskosten . Es zeigt 84%. und es ist Clustered-Index.

+4

Allgemeiner Tipp, verwenden Sie niemals RECHTE JOIN, da es für die meisten Menschen zu verwirrend ist. Wechseln Sie stattdessen zu LEFT JOIN, da es viel einfacher zu verstehen ist, dass "main table left join optionaler Daten" anstatt "optional data right join main table". – jarlh

+1

versuchen Sie, die Datensätze aus Transaktionstabelle zunächst zu filtern und dann mit den entsprechenden Tabellen zu verbinden. –

+0

@ ps_prakash02 Sie haben Recht. Jetzt reduzieren Sie eine Minute. Aber immer noch dauert 2 min 30 sec –

Antwort

0

Erstellen Sie einen Index für alle Tabellen, die Sie in Ihrer Abfrage verwenden. Das ist der bessere Weg, um das Ergebnis sehr schnell zu produzieren.

zum Beispiel

Index erstellen für Time and TransactionNumber in Transaction Table

Index erstellen für TransactionNumber, ItemID and StoreID in TransactionEntry Table

für ItemID in Item Table erstellen Index.

Bitte besuchen Sie diese Website. You can learn from the basic for query tuning and SQL optimization

+0

@DuduMarkovitz Ich hoffe, das wird die richtige Antwort sein –

+0

Ich bin verwirrt. "mohamed faisal" beantwortet Fragen von "mohamed faisal"? Ist das eine Art von Rufbildungssystem? – deroby

+0

@deroby Als ich vor einigen Jahren in Ägypten war, traf ich einen Typen namens Mohamed. Er sagte mir: "Der Name seines Onkels ist Mohamed; sein Cousin Mohamed; sein Schwager Mohamed; der Name seines Vaters war auch Mohamed; aber der Name seiner Mutter - nicht Mohamed". (Die Freuden von regional ikonischen Namen.) Davon abgesehen haben beide Mohameds Fragen mit verdächtig ähnlichen Tischen gestellt. Obwohl es vielleicht noch eine unschuldigere Erklärung gibt, wenn man bedenkt, dass Mohamed in [dieser Frage] (http://stackoverflow.com/a/41342365/224704) die Antwort von Mohamed nicht zu verstehen schien; hat es aber geschafft, es erfolgreich zu testen. –

3

Vermeiden Sie Funktionsaufrufe - sie verhindern die Verwendung von Indizes. Versuchen

Where transactions.Time >= '2015-01-01' 
    and transactions.Time < '2015-02-01' 

Wenn Sie nicht über einen Index für die Spalte transactions.Time dann einen Index für diese Spalte hinzuzufügen.

+0

Was meinst du mit 'Wenn du keinen hast, füge einen Index zu den Transaktionen hinzu.Zeit.' –

+0

Jetzt besser verständlich? –

+0

Jetzt reduziert es 24 Sek., Es reduziert das Ergebnis von 3 Min. 44 Sek. Auf 3 Min. 20 Sek. –

-1

Dieser Code Versuchen Sie, sobald es Ihnen helfen können

select transactionsEntry.StoreID StoreID,items.ItemLookupCode ItemLookupCode,SUM(transactionsEntry.Quantity) 
FROM [HQMatajer].[dbo].[TransactionEntry] transactionsEntry 
INNER JOIN [HQMatajer].[dbo].[Item] items ON transactionsEntry.ItemID = items.ID 
RIGHT JOIN [HQMatajer].[dbo].[Transaction] transactions ON transactionsEntry.TransactionNumber = transactions.TransactionNumber 
Where transactions.[Time] >= '2015-01-01' and transactions.[Time] < '2015-02-01' 
GROUP BY transactionsEntry.StoreID,items.ItemLookupCode 
ORDER BY items.ItemLookupCode 
+0

y down vote .. ?? –

+0

gibt es keinen Unterschied zu meiner Abfrage außer der Where-Klausel. Das wird auch schon vorgeschlagen. Viel Glück beim nächsten Mal –

+0

@mohamedfaisal überprüfen Sie die Abfrage erneut ..Sie besser die richtige Join nach dem inneren Join verwenden. –

0

Sie müssen den Clustered Index Scan zu verhindern.

Ich empfehle einen abdeckenden Index Erstellen auf [transactionsentry]:

Key Columns:[TransactionNumber],[ItemID] 

Include:[StoreID] 

auch versuchen, diesen Index auf [Transaktion]:

Key Columns:[time],[TransactionNumber] 

(Leider kann ich nicht mehr Tiefe bieten, aber ich Ich kenne Ihre aktuelle Indexierungsstruktur nicht.)

Verwandte Themen