web-dev-qa-db-fra.com

Opérateurs logiques OR ET en condition et ordre des conditions dans OERE

Examinons ces deux déclarations:

IF (CONDITION 1) OR (CONDITION 2)
...

IF (CONDITION 3) AND (CONDITION 4)
...

Si CONDITION 1 est TRUE, sera CONDITION 2 être vérifié?
Si CONDITION 3 est FALSE, sera CONDITION 4 être vérifié?

Qu'en est-il des conditions sur WHERE: le moteur SQL Server optimise-t-il toutes les conditions dans une clause WHERE? Si les programmeurs placent des conditions dans l'ordre droit pour être sûr que l'optimiseur SQL Server le résout dans le droit droit manière?

AJOUTÉ:

Merci à Jack pour le lien, surprise du code t-sql:

IF  1/0 = 1 OR 1 = 1
      SELECT 'True' AS result
ELSE
      SELECT 'False' AS result


IF  1/0 = 1 AND 1 = 0
      SELECT 'True' AS result
ELSE
      SELECT 'False' AS result

Il n'y a pas de levée d'exception Diviser par zéro dans ce cas.

CONCLUSION:

Si C++/C #/VB a un court-circuit, pourquoi SQL Server ne peut-il pas l'avoir?

Pour vraiment répondre à cette question, examinons comment les deux fonctionnent avec les conditions. C++/C #/VB ont tous des courts-circuits définis dans les spécifications du langage pour accélérer l'exécution du code. Pourquoi s'embêter à évaluer N OR conditions lorsque la première est déjà vraie ou M ET conditions lorsque la première est déjà fausse.

En tant que développeurs, nous devons être conscients que SQL Server fonctionne différemment. C'est un système basé sur les coûts. Pour obtenir le plan d'exécution optimal pour notre requête, le processeur de requêtes doit évaluer chaque condition et lui attribuer un coût. Ces coûts sont ensuite évalués dans leur ensemble pour former un seuil qui doit être inférieur au seuil défini que SQL Server a pour un bon plan. Si le coût est inférieur au seuil défini, le plan est utilisé, sinon tout le processus est répété avec une combinaison différente de coûts de condition. Le coût ici est soit un scan, soit une recherche, soit une jointure de fusion ou une jointure de hachage, etc. Vous pourriez penser que forcer l'utilisation de l'index sur une colonne compte comme un court-circuit, mais ce n'est pas le cas. Il force seulement l'utilisation de cet index et raccourcit ainsi la liste des plans d'exécution possibles. Le système est toujours basé sur les coûts.

En tant que développeur, vous devez savoir que SQL Server ne fait pas de court-circuit comme c'est le cas dans d'autres langages de programmation et il n'y a rien que vous puissiez faire pour le forcer.

35
garik

Il n'y a aucune garantie dans SQL Server si ou dans quel ordre les instructions seront traitées dans une clause WHERE. L'expression unique qui permet de court-circuiter les instructions est CASE-WHEN. Ce qui suit est tiré d'une réponse que j'ai publiée sur Stackoverflow:

Comment SQL Server court-circuite l'évaluation de la condition O)

Il le fait quand il en a envie, mais pas de la façon dont vous pensez immédiatement.

En tant que développeur, vous devez être conscient que SQL Server ne fait pas de court-circuit comme cela se fait dans d'autres langages de programmation et il n'y a rien que vous puissiez faire pour le forcer à .

Pour plus de détails, consultez le premier lien dans l'entrée de blog ci-dessus, qui mène à un autre blog:

SQL Server court-circuite?

Le verdict final? Eh bien, je n'en ai pas encore vraiment, mais il est probablement sûr de dire que la seule fois où vous pouvez garantir un court-circuit spécifique est lorsque vous exprimez plusieurs conditions WHEN dans une expression CASE . Avec les expressions booléennes standard, l'optimiseur déplace les choses comme bon lui semble en fonction des tables, des index et des données que vous interrogez.

27
MicSim

Dans T-SQL, l'instruction IF peut court-circuiter, mais vous ne pouvez pas vous y fier pour évaluer les expressions dans l'ordre

SQL est un langage de programmation déclaratif . Contrairement, disons, au C++ qui est un langage de programmation impératif .

C'est à dire. vous pouvez lui dire quoi vous voulez dans le résultat final, mais vous ne pouvez pas dicter comment le résultat est en cours d'exécution, tout dépend du moteur.

La seule vraie façon de garantir le "court-circuit" (ou tout autre flux de contrôle ) à l'intérieur de WHERE est d'utiliser des vues indexées, temporaires tableaux et mécanismes similaires.

PS. Vous pouvez également utiliser des conseils de plan d'exécution (pour "indiquer" au moteur comment exécuter une requête, quels index utiliser et COMMENT les utiliser), je pensais juste que je devrais le mentionner, pendant que nous sommes sur ce sujet ...

0
jitbit