281 votes

Condition de JOINTURE ou de OÙ

Quelle est la différence de performance (performance, les meilleures pratiques, etc...) entre mettre une condition dans la clause de JOINTURE contre 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'

Qui préférez-vous (et peut-être pourquoi)?

204voto

Cade Roux Points 53870

L'algèbre relationnelle permet l'interchangeabilité des prédicats dans l' WHERE de la clause et l' INNER JOIN, de sorte que même INNER JOIN des requêtes avec des WHERE clauses peuvent avoir les prédicats rearrranged par l'optimiseur de sorte qu'ils peuvent déjà être exclus lors de l' JOIN processus.

Je vous recommande d'écrire les requêtes dans la plupart des readble façon possible.

Parfois, cela inclut la mise à l' INNER JOIN relativement "incomplet" et de mettre certains critères de la WHERE tout simplement pour faire les listes de critères de filtrage plus facilement maintenable.

Par exemple, au lieu de:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

Écrire:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

Mais cela dépend, bien sûr.

182voto

HLGEM Points 54641

Pour les jointures internes, je n'ai pas vraiment remarqué une différence (mais comme avec toutes les performances de réglage, vous devez vérifier sur votre base de données dans vos conditions).

Cependant, lorsque vous mettez l'état fait une énorme différence si vous utilisez de droite ou de gauche rejoint. Par exemple tenir compte de ces deux requêtes:

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE ORD.OrderDate >'20090515'

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
AND ORD.OrderDate >'20090515'

La première sera de vous donner uniquement les enregistrements qui ont une ordonnance datée au plus tard le 15 Mai 2009 ainsi, la conversion de la gauche à se joindre à une jointure interne. La deuxième sera de donner à ces dossiers plus tous les clients n'ayant pas de commandes. L'ensemble des résultats est très différent selon l'endroit où vous mettez de l'état. (Sélectionnez * si, par exemple, seulement, vous ne devez pas utiliser de cours dans le code de production.) L'exception à cette règle est lorsque vous souhaitez afficher uniquement les enregistrements dans une table, mais pas les autres. Ensuite, vous utilisez la clause where pour la condition de ne pas le rejoindre.

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE ORD.OrderID is null

31voto

Bill Karwin Points 204877

La plupart des SGBDR produits permettra d'optimiser à la fois les requêtes de la même manière. Dans "Performances SQL Tuning" par Peter Gulutzan et Trudy Pelzer, ils ont testé plusieurs marques de SGBDR et n'a trouvé aucune différence de performances.

Je préfère garder les conditions de jointure distincte de restriction de requête conditions.

Si vous utilisez OUTER JOIN parfois, il est nécessaire de mettre les conditions de la clause de jointure.

17voto

TheTXI Points 24470

OÙ va filtrer après la JOINTURE a eu lieu.

Filtre sur la JOINTURE pour éviter les lignes d'être ajouté pendant le processus de JOINTURE.

3voto

John Nolan Points 16633

Je préfère la pour JOINDRE toutes les tables/Vues et ensuite utiliser la OÙ introduire le prédicat de l'ensemble.

Il se sent syntaxiquement plus propre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X