it-swarm.com.de

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

Betrachten Sie diese Antwort on SO das beruhigt den Fragesteller über das <> Operator, der:

<> ist das gleiche wie !=.

Aber dann meldet sich ein Kommentator und sagt:

Es ist wahr, dass sie funktional gleich sind. Die Verwendung durch den SQL-Optimierer ist jedoch sehr unterschiedlich. = /! = werden einfach als wahr/falsch bewertet, während <> bedeutet, dass die Engine prüfen muss, ob der Wert größer oder kleiner als ist, was mehr Leistungsaufwand bedeutet. Nur etwas zu beachten, wenn Sie Anfragen 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.

79
ErikE

Während des Parsens ruft SQL Server sqllang!DecodeCompOp Auf, um den Typ des vorhandenen Vergleichsoperators zu bestimmen:

(Call stack

Dies geschieht lange bevor irgendetwas im Optimierer involviert wird.

Von Vergleichsoperatoren (Transact-SQL)

(Comparison operators and meanings

sqllang!DecodeCompOp Verfolgt den Code mithilfe eines Debuggers und öffentlicher Symbole * und gibt einen Wert im Register eax ** wie folgt zurück:

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

!= Und <> Geben beide 5 zurück, sodass in allen späteren Operationen (einschließlich Kompilierung und Optimierung) nicht zu unterscheiden ist .


Obwohl sekundär zum obigen Punkt, ist es auch möglich (z. B. unter Verwendung des undokumentierten Ablaufverfolgungsflags 8605), den an den Optimierer übergebenen logischen Baum zu überprüfen, um zu bestätigen, dass sowohl != Als auch <>ScaOp_Comp x_cmpNe (Nicht gleich Skalaroperatorvergleich).

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 Mit Minidumps tiefer in SQL Server eintauchen vom SQL Server-Kundenberatungsteam und SQL Server-Debugging mit WinDbg - eine Einführung von Klaus Aschenbrenner.

** Die Verwendung von EAX auf 32-Bit-Intel-Derivaten für Rückgabewerte von 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-Tagen erbt, als AX für den gleichen Zweck verwendet wurde - Michael Kjörling

149
Paul White 9

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

60
stacylaray

Ich denke, das Folgende beweist, dass <> führt keine 2 Vergleiche durch.

  1. SQL Standard 92 definiert <> als nicht gleich Operator, ( http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ). Technisch gesehen != ist eine Erweiterung des Standards (obwohl ich mir kein RDBMS vorstellen kann, das es nicht implementiert).
  2. Wenn SQLServer <> als 2 Operatoren, nicht einer, würde es dasselbe für >< was tatsächlich ein Syntaxfehler ist.
8
a1ex07

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

! = (Nicht gleich) (Transact-SQL)

Und wenn Sie sich einen Ausführungsplan ansehen, in dem != wird verwendet, unter Prädikat ändert sich != bis <>.

1
Ryan Cooper