Angesichts dieser Frage zu reddit habe ich die Abfrage bereinigt, um darauf hinzuweisen, wo sich das Problem in der Abfrage befand. Ich verwende zuerst ein Komma und WHERE 1=1
um das Ändern von Abfragen zu vereinfachen. Daher enden meine Abfragen im Allgemeinen so:
SELECT
C.CompanyName
,O.ShippedDate
,OD.UnitPrice
,P.ProductName
FROM
Customers as C
INNER JOIN Orders as O ON C.CustomerID = O.CustomerID
INNER JOIN [Order Details] as OD ON O.OrderID = OD.OrderID
INNER JOIN Products as P ON P.ProductID = OD.ProductID
Where 1=1
-- AND O.ShippedDate Between '4/1/2008' And '4/30/2008'
And P.productname = 'TOFU'
Order By C.CompanyName
Jemand sagte im Grunde, dass 1 = 1 im Allgemeinen faul und schlecht für die Leistung ist .
Da ich nicht "vorzeitig optimieren" möchte, möchte ich gute Praktiken befolgen. Ich habe mir zuvor die Abfragepläne angesehen, aber im Allgemeinen nur, um herauszufinden, welche Indizes ich hinzufügen (oder anpassen) kann, damit meine Abfragen schneller ausgeführt werden.
Die Frage ist dann wirklich, ob ... Where 1=1
schlimme Dinge passieren? Und wenn ja, wie kann ich das beurteilen?
Minor Edit: Ich habe auch immer "angenommen", dass 1=1
das optimiert oder im schlimmsten Fall vernachlässigbar wäre. Es tut niemals weh, ein Mantra wie "Goto's are Evil" oder "Premature Optimization ..." oder andere vermutete Fakten in Frage zu stellen. War nicht sicher, ob sich 1=1 AND
dies realistisch auf die Abfragepläne auswirken würde oder nicht. Was ist mit Unterabfragen? CTE? Prozeduren?
Ich bin nicht derjenige, der optimiert, es sei denn, er wird benötigt ... aber wenn ich etwas "Schlechtes" mache, möchte ich die Effekte minimieren oder gegebenenfalls ändern.
quelle
Antworten:
Der SQL Server
ParserDas Optimierungsprogramm verfügt über die Funktion "Konstante Faltung", mit der tautologische Ausdrücke aus der Abfrage entfernt werden.Wenn Sie sich den Ausführungsplan ansehen, wird an keiner Stelle in den Prädikaten dieser Ausdruck angezeigt. Dies impliziert, dass aus diesem und anderen Gründen eine konstante Faltung ohnehin zur Kompilierungszeit durchgeführt wird und keine Auswirkung auf die Abfrageleistung hat.
Weitere Informationen finden Sie unter Konstante Faltung und Auswertung des Ausdrucks während der Kardinalitätsschätzung .
quelle
Das Hinzufügen des redundanten Vergleichselements kann in SQL Server einen Unterschied bewirken.
In den folgenden Ausführungsplänen wird das Wort
@1
im ersten Plan gegenüber dem Wort'foo'
im zweiten Plan angegeben.Dies weist darauf hin, dass SQL Server die erste Abfrage für eine einfache Parametrisierung war , um die Wiederverwendung des Ausführungsplans zu fördern. Der Vergleich zweier Konstanten verhindert dies jedoch im zweiten Fall.
Eine Liste der Bedingungen, die eine einfache Parametrisierung verhindern (früher als automatische Parametrisierung bezeichnet), finden Sie in Anhang A des Microsoft Technical Papers Plan Caching:
Eine einfache Parametrierung ist jedoch in der Regel nicht das, worauf Sie sich verlassen sollten. Es ist weitaus besser, Ihre Abfragen explizit zu parametrisieren.
quelle
In modernen RDBMS (einschließlich Oracle, Microsoft SQL Server und PostgreSQL - da bin ich mir sicher) hat dies keine Auswirkungen auf die Leistung.
Wie bereits erwähnt, wirkt sich dies nur auf die Abfrageplanungsphase aus. Daher wird der Unterschied nur sichtbar, wenn Sie Tausende von Iterationen einer simplen Abfrage ausführen, die keine Daten zurückgibt, wie die folgende:
Für mich ist dies unter PostgreSQL 9.0 nur mit 10000 Iterationen sichtbar:
quelle
Dies kann für Oracle ein "Problem" sein, wenn Sie den Datenbankparameter cursor_sharing verwenden. Wenn dies auf "force" gesetzt ist, werden alle SQL-Anweisungen geändert. Alle "Konstanten" in Abfragen werden durch Bindevariablen ersetzt (wie 1 =>: SYS_0).
Diese Option wurde eingeführt, um mit einigen faulen Entwicklern fertig zu werden. Andererseits kann es auch anderen faulen Entwicklern schaden. Das Risiko ist aber nicht zu hoch. Seit 11g hat es variable Peeking-Funktion binden.
quelle