Autorisierende Quelle, deren Leistung in SQL Server mit <> und! = Identisch ist

74

Betrachten Sie diese Antwort auf SO, um dem Fragesteller zu versichern <>, dass:

<>ist ... dasselbe wie !=.

Dann meldet sich ein Kommentator und sagt:

Es ist wahr, dass sie funktionell gleich sind. Die Verwendung durch den SQL-Optimierer ist jedoch sehr unterschiedlich. = /! = werden einfach als wahr / falsch ausgewertet, während <> bedeutet, dass die Engine prüfen muss, ob der Wert größer oder kleiner ist, was einen höheren Leistungsaufwand bedeutet. Nur etwas zu beachten, wenn Sie Abfragen schreiben, die teuer sein können.

Ich bin zuversichtlich, dass dies falsch ist, aber um potenzielle Skeptiker anzusprechen, frage ich mich, ob jemand eine maßgebliche oder kanonische Quelle liefern kann, um zu beweisen, dass diese Operatoren nicht nur funktional gleich, sondern in allen Aspekten identisch sind.

ErikE
quelle

Antworten:

144

Während des Parsens ermittelt SQL Server sqllang!DecodeCompOpden Typ des vorhandenen Vergleichsoperators:

Stack aufrufen

Dies geschieht lange bevor irgendetwas im Optimierer involviert wird.

Von Vergleichsoperatoren (Transact-SQL)

Vergleichsoperatoren und Bedeutungen

Wenn Sie den Code mithilfe eines Debuggers und öffentlicher Symbole * sqllang!DecodeCompOpverfolgen, wird ein Wert im Register eax** wie folgt zurückgegeben:

╔════╦══════╗
║ Op ║ Code ║
╠════╬══════╣
║ <  ║    1 ║
║ =  ║    2 ║
║ <= ║    3 ║
║ !> ║    3 ║
║ >  ║    4 ║
║ <> ║    5 ║
║ != ║    5 ║
║ >= ║    6 ║
║ !< ║    6 ║
╚════╩══════╝

!=und <>beide 5 zurückkehren, so sind nicht zu unterscheiden in allen späteren Operationen (einschließlich Erstellung und Optimierung).


Obwohl ein Zusatz zu dem oben genannten Punkt, ist es auch möglich (zB mit undokumentierte Trace - Flag 8605) in der logischen Struktur für das Optimierungsprogramm übergeben zu sehen , dass sowohl zu bestätigen !=und <>Karte auf ScaOp_Comp x_cmpNe(nicht gleich skalar Operator Vergleich).

Zum Beispiel:

SELECT P.ProductID FROM Production.Product AS P
WHERE P.ProductID != 4
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);

SELECT P.ProductID FROM Production.Product AS P
WHERE P.ProductID <> 4
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);

beide produzieren:

LogOp_Project QCOL: [P] .ProductID
    LogOp_Select
        LogOp_Get TBL: Production.Product (Alias ​​TBL: P)
        ScaOp_Comp x_cmpNe
            ScaOp_Identifier QCOL: [P] .ProductID
            ScaOp_Const TI (int, ML = 4) XVAR (int, nicht im Besitz, Wert = 4)
    AncOp_PrjList 

Fußnoten

* Ich benutze WinDbg ; andere Debugger sind verfügbar. Öffentliche Symbole sind über den üblichen Microsoft-Symbolserver verfügbar. Weitere Informationen finden Sie unter Weitere Informationen zu SQL Server mithilfe von Minidumps des SQL Server-Kundenberatungsteams und unter Debuggen von SQL Server mit WinDbg - eine Einführung von Klaus Aschenbrenner.

** Die Verwendung von EAX für 32-Bit-Intel-Derivate für Rückgabewerte einer Funktion ist üblich. Sicherlich macht das Win32-ABI das so, und ich bin mir ziemlich sicher, dass es diese Praxis aus früheren MS-DOS-Zeiten erbt, als AX für denselben Zweck verwendet wurde - Michael Kjörling

Paul White
quelle
58

Ich arbeite bei Microsoft im SQL-Support und habe Jack Li, Senior Escalation Engineer und Fachexperte für SQL Server-Leistung, gefragt: "Behandelt SQL! = Etwas anderes als <>?" und er sagte: "Sie sind die gleichen."

Stacylaray
quelle
8

Ich denke, das Folgende beweist, dass <>es keine zwei Vergleiche gibt.

  1. SQL Standard 92 definiert <>als nicht gleich Operator ( http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ). Technisch gesehen !=handelt es sich um eine Erweiterung des Standards (obwohl ich mir kein RDBMS vorstellen kann, das es nicht implementiert).
  2. Wenn SQLServer <>als zwei Operatoren behandelt wird , und nicht als einer, wird dasselbe getan, ><was in Wirklichkeit ein Syntaxfehler ist.
a1ex07
quelle
1

Das ist falsch, Books Online (BOL) sagt, dass sie funktional identisch sind:

! = (Nicht gleich) (Transact-SQL)

Wenn Sie sich einen Ausführungsplan ansehen !=, in dem Predicate verwendet wird, ändert sich dieser != in <>.

Ryan Cooper
quelle
2
Das Problem ist, dass die Sprache "funktional gleich" bereits in dem angegebenen Kommentar zugelassen ist, aber eine zusätzliche Unterscheidung bezüglich der Leistung vornimmt, obwohl Sie und ich wissen, dass "funktional gleich" die tatsächliche Funktionsweise und alle Leistungsmerkmale umfasst. Was würde man tun, wenn man dies jenseits aller entschlossenen Skepsis beweisen würde?
ErikE