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"
Je pense que le second est plus rapide car le critère le plus unique (LastName
) vient en premier dans la clause where
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?
Non, cet ordre n'a pas d'importance (ou du moins: ne devrait pas avoir d'importance).
Tout optimiseur de requête correct examinera toutes les parties de la clause WHERE
et déterminera 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 les autres SGBDR auront des stratégies similaires.
Ce qui compte, c'est si vous avez 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'autre part - encore une fois pour SQL Server - si vous utilisez SELECT *
saisir tout colonnes d’une table, et la table est plutôt petite; il est donc fort probable que l’optimiseur de requête effectue simplement une analyse de la table (ou de l’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 trop chère très rapidement).
L'ordre des clauses WHERE ne devrait pas faire de différence dans une base de données conforme au standard 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 la commande. Ce qui suit génère une erreur dans SQL Server:
select *
from INFORMATION_SCHEMA.TABLES
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0
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, elle échoue, fournissant un exemple clair que SQL Server (comme les autres bases de données) ne se soucie pas de l'ordre des clauses dans l'instruction WHERE.
ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf
6.3.3.3 Ordre d'évaluation de la règle
...
Lorsque la priorité n'est pas déterminée par les formats ou par les parenthèses, l'évaluation efficace des expressions est généralement effectuée de gauche à droite. Toutefois, l'implémentation dépend du fait que les expressions soient réellement évaluées de gauche à droite, en particulier lorsque des opérandes ou des opérateurs peuvent provoquer la création 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é de ici
Non, tous les RDBM commencent d'abord par analyser la requête et l'optimisent 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 Explication dans Oracle, par exemple).
M.
Déclaration OP originale
Je pense que le second est plus rapide car le critère le plus unique (LastName) vient en premier dans la clause where, et les enregistrements seront éliminés plus efficacement. Je ne pense pas que l'optimiseur soit assez intelligent pour optimiser le premier SQL.
Je suppose que vous confondez cela avec la sélection de l'ordre des colonnes lors de la création des index dans lesquels vous devez placer les colonnes les plus sélectives en premier lieu, puis les secondes les plus sélectives, etc.
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.
C'est vrai dans la mesure où cela se passe, à condition que les noms ne soient pas indexés. Des données différentes le rendraient faux cependant. Afin de déterminer le moyen de le faire, qui peut différer à chaque fois, le SGBD devrait exécuter une requête de décompte distincte pour chaque colonne et comparer les chiffres, ce qui coûterait plus que simplement hausser les épaules et aller de l'avant.