Gut, schlecht oder gleichgültig: WO 1 = 1

14

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=1um 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=1schlimme Dinge passieren? Und wenn ja, wie kann ich das beurteilen?

Minor Edit: Ich habe auch immer "angenommen", dass 1=1das 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 ANDdies 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.

WernerCD
quelle
2
Nein, würde es nicht. Abgesehen von ein paar Mikrosekunden, damit der Optimierer den redundanten Zustand beseitigt. Sie sollten sich besser darauf konzentrieren, dass Ihre Date-Literale nicht mehrdeutig sind.
ypercubeᵀᴹ
Wie @ypercube sagte, macht es keinen Unterschied. Der Abfrageoptimierer müsste ein Stück **** sein, damit so etwas einen Unterschied macht;)
Philᵀᴹ
4
Glauben Sie nicht alles, was Sie auf reddit lesen. Bitte.
Aaron Bertrand
1
@AaronBertrand Ich nehme alles mit einem Körnchen Salz, bis ich es aus erster Hand erlebt habe. Ich werde immer noch eine Frage stellen, die plausibel klingt, und herausfinden, ob es etwas Wahres gibt, insbesondere, wenn es sich auf meine tägliche Arbeit auswirkt.
WernerCD
4
Es gibt Salzkörner, dann gibt es den Salzgehalt eines ganzen Ozeans, der auf Ihrem Bürogebäude abgeladen ist: P
Philᵀᴹ

Antworten:

13

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 .

Spaghettidba
quelle
Es ist wahrscheinlich weg kompiliert, weil dies ein bekanntes Muster für die Verkettung von Feldern ist.
Jcolebrand
Nein, es wird weg kompiliert, weil es tautologisch ist. Es würde genauso funktionieren mit 2736 = 2736, was nicht so üblich ist wie 1 = 1. Gleiches gilt für Widersprüche. In diesem Fall wird das Merkmal "Widerspruchserkennung" genannt.
Spaghettidba
Welcher Teil des "bekannten Musters" bedeutete "muss 1 = 1 sein"?
Jcolebrand
9

Das Hinzufügen des redundanten Vergleichselements kann in SQL Server einen Unterschied bewirken.

In den folgenden Ausführungsplänen wird das Wort @1im ersten Plan gegenüber dem Wort 'foo'im zweiten Plan angegeben.

Bildbeschreibung hier eingeben

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.

Martin Smith
quelle
4

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:

SELECT 1 FROM empty_table; -- run this 10 000 times.

SELECT 1 FROM empty_table WHERE 1=1; -- run this 10 000 times and compare.

Für mich ist dies unter PostgreSQL 9.0 nur mit 10000 Iterationen sichtbar:

filip@srv:~$ pgquerybench.pl -h /var/run/postgresql/ -q "select 1 from never where 1=1" -q "select 1 from never" -i 10000
Iterations: 10000
Query:   select 1 from never where 1=1
Total:   2.952 s
Average: 0.295 ms
Query:   select 1 from never
Total:   2.850 s
Average: 0.285 ms
filiprem
quelle
0

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.

ibre5041
quelle
Können Sie erklären, was "Seit 11g hat es variable Peeking-Funktion binden." meint?
Ypercubeᵀᴹ
@ypercube "Bindevariablen-Peeking" bedeutet, dass das Optimierungsprogramm die tatsächlichen Werte von Bindevariablen beobachtet und Datenstatistiken verwendet, um den Abfrageausführungsplan neu zu bewerten und möglicherweise neu zu generieren. Ich bezweifle, dass das Spähen Auswirkungen auf das derzeit diskutierte Konstrukt hat, da es nicht von der Datenstatistik abhängt.
Mustaccio