2016-08-04 48 views
2

Wie kann ich Leistung der unten genannten Abfrage optimieren, wenn die Tabellenstruktur im Bild ist unterOptimieren schließen sich aus mehreren Tabellen

Pic Showing The Table Structure

select CounterID, OutletTitle, CounterTitle 
from(
    select OutletID, Text as OutletTitle 
    from Outlets as q1 
    inner join 
    TranslationTexts as tt 
    on q1.TitleID=tt.TranslationID 
    where tt.Locale='ar-SA' and q1.CompanyID=311 and q1.OutletID=8 --Locale & CompanyID & OutletID 
    ) as O  
inner join  
(
    select CounterID, Text as CounterTitle, OutletID 
    from Counters as q1 
    inner join 
    TranslationTexts as tt 
    on q1.TitleID=tt.TranslationID 
    where tt.Locale='ar-SA' and q1.OutletID=8 --Locale & OutletID 
) as C 
on O.OutletID=C.OutletID 
+0

Wenn Sie Ihre Frage so bearbeiten, dass sie Beispieldaten und gewünschte Ergebnisse enthält, können andere besser verstehen, was mit Ihrer Abfrage geschehen soll. –

+0

Wenn tt.Locale einen kleinen Bereich von Werten hat, können Sie dafür eine Dictionary-Tabelle erstellen und den Fremdschlüssel in einer Where-Klausel verwenden - die Suche über Varchar-Daten ist langsam. Außerdem haben Sie ziemlich ähnliche where-Klauseln in Ihren beiden Unterabfragen - denken Sie, wenn Sie es in die äußere Abfrage verschieben können, um die gleiche Operation nicht zweimal auszuführen. – PacoDePaco

Antwort

1

Dies ist ein anderer Ansatz, wie dargestellt. Ich kann nicht über die Verbesserung der Leistung sagen, weil das von vielen anderen Dingen abhängt, aber ich glaube, es ist eine äquivalente Version und eine leichtere zu lesen.

SELECT 
    C.CounterID 
    , tt.Text AS OutletTitle 
    , tt.Text AS CounterTitle 
FROM 
    Outlets AS q1 
    INNER JOIN TranslationTexts AS tt ON q1.TitleID=tt.TranslationID 
    INNER JOIN Counters C ON c.OutletID=q1.OutletID 
    INNER JOIN TranslationTexts AS tt2 ON tt2.TranslationID=tt.TranslationID AND tt2.Locale=tt.Locale 
WHERE 
    tt.Locale='ar-SA' and q1.CompanyID=311 and q1.OutletID=8; 
2

Sie sollten diesen Wunsch versuchen:

SELECT CounterID, tou.Text as OutletTitle, tco.Text as CounterTitle 
FROM Counters as co 
    INNER JOIN Outlets as ou ON co.OutletID = ou.OutletID 
    INNER JOIN TranslationTexts as tco on co.TitleID=tco.TranslationID 
    INNER JOIN TranslationTexts as tou on ou.TitleID=tou.TranslationID 
WHERE co.CompanyID=311 and co.OutletID=8 AND tco.Locale='ar-SA' and tou.Locale='ar-SA' 

viel bessere Leistung zu haben, einige Indizes auf den 3 Tabellen hinzufügen könnte.

+0

Die Abfrage lief gut und das Ergebnis war nach der Indexierung viel besser. Danke für den Code. –

1

Die Frage ist, was Sie optimieren möchten .. Lesbarkeit (und Wartbarkeit) und/oder Leistung?

Die meisten Leute haben ihren eigenen "Stil" beim Schreiben von Abfragen. Ich bevorzuge das untenstehende, aber auf dem Server wird es wahrscheinlich gleich aussehen und höchstwahrscheinlich wird das System genau die gleiche Menge an "Arbeit" haben, um die Daten zu bekommen, auch wenn es für uns Menschen anders aussieht. Ich würde vorschlagen, ein wenig herum zu googeln und zu lernen, wie man einen Abfrageplan interpretiert.

SELECT q2.CounterID, 
     tt1.Text as OutletTitle, 
     tt2.Text as CounterTitle 

FROM Outlets as q1 

INNER JOIN Counters as q2 
     ON q2.OutletID = q1.OutletID 

INNER JOIN TranslationTexts as tt1 
     ON tt1.TranslationID = q1.TitleID 
     AND tt1.Locale  = 'ar-SA' 

INNER JOIN TranslationTexts as tt2 
     ON tt2.TranslationID = q2.TitleID 
     AND tt2.Locale  = 'ar-SA' 

WHERE q1.CompanyID = 311 
    AND q1.OutletID = 8 

Auf der Dinge, die ich bemerken ist, dass Sie sowohl CompanyID und OutletID als Filter für die Outlets Tabelle übergeben. Da OutletID der Primärschlüssel dieser Tabelle ist, frage ich mich, ob Sie wirklich den Filter auf CompanyID benötigen. Im besten Fall wird es die Aufzeichnung beseitigen, weil es die falsche Firma ist, aber irgendwie habe ich den Eindruck, dass Sie bereits die richtige CompanyID kennen.

Was die Leistung, würde ich diese Indizes beraten

CREATE INDEX idx_Locale ON TranslationTexts (Locale, Translation_id) 
CREATE INDEX idx_CompanyID ON Outlets (CompanyID) INCLUDE (TitleID, OutletID) 

Höchstwahrscheinlich werden Sie auch diesen Index auf Local ein UNIQUE Index machen es noch besser zu machen arbeiten.

+0

Ich versuche, Leistung zu erzielen, da die Aufzeichnungen viel zu viel sind, und Wartbarkeit ist hier weniger wichtig. Wie auch immer, ich habe den Code aus der obigen Antwort ausprobiert. Danke für den Code und die Hilfe. –

+0

Nun, das Neuformatieren des Codes wird nur eine geringfügige Auswirkung haben; Die Indizes sollten jedoch zu einer deutlichen Verbesserung führen. Viel Glück! – deroby