Y a-t-il une différence (performances, bonnes pratiques, etc.) entre la mise d'une condition dans la clause JOIN et la clause WHERE?
Par exemple...
-- Condition in JOIN
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD
ON CUS.CustomerID = ORD.CustomerID
AND CUS.FirstName = 'John'
-- Condition in WHERE
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD
ON CUS.CustomerID = ORD.CustomerID
WHERE CUS.FirstName = 'John'
Lequel préférez-vous (et peut-être pourquoi)?
sql
performance
Steve Dignan
la source
la source
FROM Orders JOIN OrderParties ON Orders.Id = OrderParties.Order AND OrderParties.Type = 'Recipient' WHERE Orders.Status = 'Canceled'
Réponses:
L'algèbre relationnelle permet l'interchangeabilité des prédicats dans la
WHERE
clause et leINNER JOIN
, de sorte que même lesINNER JOIN
requêtes avec desWHERE
clauses peuvent avoir les prédicats réorganisés par l'optimiseur afin qu'ils puissent déjà être exclus pendant leJOIN
processus.Je vous recommande d'écrire les requêtes de la manière la plus lisible possible.
Parfois, cela implique de rendre les
INNER JOIN
critères relativement "incomplets" et d'insérer certains des critèresWHERE
simplement pour rendre les listes de critères de filtrage plus faciles à maintenir.Par exemple, au lieu de:
Écrire:
Mais cela dépend, bien sûr.
la source
Pour les jointures internes, je n'ai pas vraiment remarqué de différence (mais comme pour tous les réglages de performances, vous devez vérifier votre base de données dans vos conditions).
Cependant, l'emplacement de la condition fait une énorme différence si vous utilisez des jointures gauche ou droite. Par exemple, considérez ces deux requêtes:
Le premier ne vous donnera que les enregistrements dont l'ordre est postérieur au 15 mai 2009, convertissant ainsi la jointure gauche en jointure interne.
Le second donnera ces enregistrements ainsi que tous les clients sans commande. L'ensemble de résultats est très différent selon l'endroit où vous placez la condition. (Sélectionnez * à titre d'exemple uniquement, bien sûr, vous ne devez pas l'utiliser dans le code de production.)
L'exception à cela est lorsque vous souhaitez afficher uniquement les enregistrements dans une table mais pas dans l'autre. Ensuite, vous utilisez la clause where pour la condition et non la jointure.
la source
A left join B
est-ce que chaque ligne de A est jointe à chaque ligne correspondante de B. Si B n'a pas de ligne qui correspond, alors les colonnes A ont une valeur mais chaque colonne de B sur cette ligne s'affiche comme des valeurs NULL. Si vous avez écrit,where B.somecolumn = ‘somevalue’
alors vous avez un NULL (B.somecolumn) comparé à 'somevalue'. Tout ce qui est comparé à NULL est faux, donc toutes vos lignes où il n'y a pas de ligne B correspondante pour la ligne A, sont éliminées, et les résultats que vous obtenez sont les mêmes que ceux d'une jointure intérieure donnerait, par conséquent la jointure externe est devenue une jointure internefunds
jointure interne sur (prospects.id = funds.lead_id et prospects.is_manual = 'no') et SELECT funds.id, prospects.id FROMfunds
left rejoignez des prospects sur (prospects.id = funds.lead_id) où prospects.is_manual = 'no'La plupart des produits SGBDR optimiseront les deux requêtes de manière identique. Dans «SQL Performance Tuning» de Peter Gulutzan et Trudy Pelzer, ils ont testé plusieurs marques de SGBDR et n'ont trouvé aucune différence de performances.
Je préfère garder les conditions de jointure séparées des conditions de restriction de requête.
Si vous utilisez
OUTER JOIN
parfois, il est nécessaire de mettre des conditions dans la clause de jointure.la source
WHERE filtrera après la jointure.
Filtrez sur JOIN pour empêcher l'ajout de lignes pendant le processus JOIN.
la source
ON
Je préfère le JOIN pour joindre des tables / vues complètes, puis utiliser le WHERE pour introduire le prédicat de l'ensemble résultant.
Il semble syntaxiquement plus propre.
la source
Je constate généralement une augmentation des performances lors du filtrage sur la jointure. Surtout si vous pouvez joindre des colonnes indexées pour les deux tables. Vous devriez être en mesure de réduire les lectures logiques avec la plupart des requêtes qui le font également, ce qui, dans un environnement à volume élevé, est un bien meilleur indicateur de performances que le temps d'exécution.
Je suis toujours légèrement amusé quand quelqu'un montre son benchmarking SQL et qu'il a exécuté les deux versions d'un sproc 50 000 fois à minuit sur le serveur de développement et compare les temps moyens.
la source
Mettre la condition dans la jointure me semble «sémantiquement faux», car ce n'est pas pour cela que les JOINs sont «pour». Mais c'est très qualitatif.
Problème supplémentaire: si vous décidez de passer d'une jointure interne à, par exemple, une jointure droite, le fait que la condition se trouve à l'intérieur de la jointure peut entraîner des résultats inattendus.
la source
Les jointures sont à mon avis plus rapides lorsque vous avez une table plus grande. Ce n'est vraiment pas une grande différence, surtout si vous avez affaire à une table un peu plus petite. Quand j'ai découvert les jointures pour la première fois, on m'a dit que les conditions dans les jointures étaient exactement comme les conditions de la clause where et que je pourrais les utiliser de manière interchangeable si la clause where était spécifique à la table sur laquelle appliquer la condition.
la source
Il est préférable d'ajouter la condition dans la jointure. Les performances sont plus importantes que la lisibilité. Pour les grands ensembles de données, c'est important.
la source