Disons que j'ai une table appelée PEOPLE
ayant 3 colonnes ID, LastName, FirstName
, aucune de ces colonnes n'est indexée.
LastName
est plus unique et FirstName
est moins unique.
Si je fais 2 recherches:
select * from PEOPLE where FirstName="F" and LastName="L"
select * from PEOPLE where LastName="L" and FirstName="F"
Ma conviction est que le second est plus rapide car le critère le plus unique ( LastName
) vient en premier dans la where
clause, et les enregistrements seront éliminés plus efficacement. Je ne pense pas que l'optimiseur soit assez intelligent pour optimiser le premier sql.
Ma compréhension est-elle correcte?
sql
performance
where-clause
Ziyang Zhang
la source
la source
Réponses:
Non, cet ordre n'a pas d'importance (ou du moins: ne devrait pas avoir d'importance).
Tout optimiseur de requête décent examinera toutes les parties du
WHERE
clause et trouvera le moyen le plus efficace de satisfaire cette requête.Je sais que l'optimiseur de requêtes SQL Server choisira un index approprié - quel que soit l'ordre dans lequel vous avez vos deux conditions. Je suppose que d'autres SGBDR auront des stratégies similaires.
Ce qui compte, c'est que vous ayez ou non un index approprié pour cela!
Dans le cas de SQL Server, il utilisera probablement un index si vous avez:
(LastName, FirstName)
(FirstName, LastName)
(LastName)
, ou juste(FirstName)
(ou les deux)D'un autre côté - encore une fois pour SQL Server - si vous utilisez
SELECT *
pour récupérer toutes les colonnes d'une table et que la table est plutôt petite, il y a de fortes chances que l'optimiseur de requête effectue simplement une analyse de table (ou d'index clusterisé) au lieu d'utiliser un index (car la recherche dans la page de données complète pour obtenir toutes les autres colonnes devient tout simplement trop coûteuse très rapidement).la source
WHERE T1.col_1/T2.col_2 > 10 AND T2.col_2 <> 0
et j'ai eu uneDIVIDE BY 0
erreur. Après avoir changé l'ordre les conditions, la requête s'est exécutée avec succès. Ensuite, j'ai inversé la commande pour que je m'attende à obtenir l'erreur à nouveau, mais cette fois, cela a fonctionné! En fin de compte, ma conclusion a été que pour la première exécution, la commande importe, jusqu'à ce que le plan d'exécution soit construit. 'Peu importe' car le plan d'optimisation / d'exécution s'en chargeraL'ordre des clauses WHERE ne doit pas faire de différence dans une base de données conforme à la norme SQL. L'ordre d'évaluation n'est pas garanti dans la plupart des bases de données.
Ne pensez pas que SQL se soucie de l'ordre. Ce qui suit génère une erreur dans SQL Server:
Si la première partie de cette clause était exécutée en premier, seuls les noms de table numériques seraient convertis en entiers. Cependant, il échoue, fournissant un exemple clair que SQL Server (comme avec d'autres bases de données) ne se soucie pas de l'ordre des clauses dans l'instruction WHERE.
la source
ISNUMERIC(table_name) = 1
été évalué en premier, alorsCAST
ne serait appelé que pour les noms de table numériques. Mais comme il n'est pas évalué en premier, ilCAST
est également évalué pour les noms de table non numériques, ce qui provoque le message d'erreur.ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf
6.3.3.3 Ordre d'évaluation des règles
...
Lorsque la priorité n'est pas déterminée par les formats ou par des parenthèses, une évaluation efficace des expressions est généralement effectuée de gauche à droite. Cependant, le fait que les expressions soient réellement évaluées de gauche à droite dépend de l'implémentation, en particulier lorsque des opérandes ou des opérateurs peuvent provoquer le déclenchement de conditions ou si les résultats des expressions peuvent être déterminés sans évaluer complètement toutes les parties de l'expression.
copié d' ici
la source
Non, tous les RDBM commencent d'abord par analyser la requête et l'optimiser en réorganisant votre clause where.
En fonction du RDBM que vous utilisez, vous pouvez afficher le résultat de l'analyse (recherchez le plan d'explication dans Oracle par exemple)
M.
la source
Déclaration OP originale
Je suppose que vous confondez cela avec la sélection de l'ordre des colonnes tout en créant les index dans lesquels vous devez placer les colonnes les plus sélectives en premier que les deuxièmes les plus sélectives et ainsi de suite.
BTW, pour les deux requêtes ci-dessus, l'optimiseur de serveur SQL ne fera aucune optimisation mais utilisera le plan Trivila tant que le coût total du plan est inférieur au coût du seuil de parallélisme.
la source
C'est vrai pour autant, en supposant que les noms ne soient pas indexés. Des données différentes rendraient les choses erronées cependant. Afin de trouver la manière de le faire, qui pourrait différer à chaque fois, le SGBD devrait exécuter une requête de comptage distincte pour chaque colonne et comparer les nombres, ce qui coûterait plus que simplement hausser les épaules et continuer.
la source