web-dev-qa-db-fra.com

Source faisant autorité qui <> et! = Sont identiques dans les performances dans SQL Server

Considérez cette réponse sur SO qui rassure le demandeur sur le <> opérateur qui:

<> est le même que !=.

Mais alors un commentateur lance et dit:

C'est vrai qu'ils sont, fonctionnellement, les mêmes. Cependant, la façon dont l'optimiseur SQL les utilise est très différente. = /! = sont simplement évalués comme vrais/faux tandis que <> signifie que le moteur doit regarder et voir si la valeur est supérieure ou inférieure à, ce qui signifie plus de surcharge de performances. Juste quelque chose à considérer lors de l'écriture de requêtes qui peuvent être coûteuses.

Je suis convaincu que c'est faux, mais afin de répondre aux sceptiques potentiels, je me demande si quelqu'un peut fournir une source faisant autorité ou canonique pour prouver que ces opérateurs ne sont pas simplement les mêmes fonctionnellement, mais identiques à tous égards?

79
ErikE

Pendant l'analyse , SQL Server appelle sqllang!DecodeCompOp pour déterminer le type d'opérateur de comparaison présent:

Call stack

Cela se produit bien avant que quoi que ce soit dans l'optimiseur ne soit impliqué.

De Opérateurs de comparaison (Transact-SQL)

Comparison operators and meanings

Traçage du code à l'aide d'un débogueur et de symboles publics *, sqllang!DecodeCompOp renvoie une valeur dans le registre eax ** comme suit:

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

!= et <> les deux renvoient 5, ainsi sont indiscernables dans toutes les opérations ultérieures (y compris la compilation et l'optimisation).


Bien que secondaire par rapport au point ci-dessus, il est également possible (par exemple en utilisant l'indicateur de trace non documenté 8605) de regarder l'arborescence logique transmise à l'optimiseur pour confirmer que les deux != et <> carte pour ScaOp_Comp x_cmpNe (comparaison d'opérateurs scalaires différents).

Par exemple:

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);

les deux produisent:

 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, Not Owned, Value = 4) 
 AncOp_PrjList 

Notes de bas de page

* J'utilise WinDbg ; d'autres débogueurs sont disponibles. Les symboles publics sont disponibles via le serveur de symboles Microsoft habituel. Pour plus d'informations, consultez Approfondissement de SQL Server à l'aide de Minidumps par l'équipe de conseil client SQL Server et Débogage SQL Server avec WinDbg - une introduction par Klaus Aschenbrenner.

** L'utilisation d'EAA sur les dérivés Intel 32 bits pour les valeurs de retour d'une fonction est courante. Certes, le Win32 ABI le fait de cette façon, et je suis presque sûr qu'il hérite de cette pratique des temps anciens MS-DOS, où AX était utilisé dans le même but - Michael Kjörling

149
Paul White 9

Je travaille chez Microsoft dans le support SQL et j'ai demandé à Jack Li, ingénieur principal en escalade et expert en la matière des performances de SQL Server, "SQL traite-t-il! = Différemment de <>?" et il a dit: "Ce sont les mêmes."

60
stacylaray

Je pense que ce qui suit prouve que <> ne fait pas 2 comparaisons.

  1. SQL Standard 92 définit <> comme opérateur différent de, ( http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ). Techniquement, != est une extension de la norme (même si je ne peux penser à aucun SGBDR qui ne l'implémente pas).
  2. Si SQLServer a traité <> comme 2 opérateurs, pas un, il ferait de même pour >< qui est en fait une erreur de syntaxe.
8
a1ex07

C'est incorrect, Books Online (BOL) dit qu'ils sont fonctionnellement les mêmes:

! = (Différent de) (Transact-SQL)

Et si vous regardez un plan d'exécution où != est utilisé, sous Prédicat, il change != à <>.

1
Ryan Cooper