Critères de filtre SQL dans les critères de jointure ou la clause where qui est plus efficace

StackOverflow https://stackoverflow.com/questions/1401889

Question

J'ai une requête relativement simple joignant deux tables. Le & Quot; Où & Quot; Les critères peuvent être exprimés soit dans les critères de jointure, soit sous la forme d'une clause where. Je me demande ce qui est le plus efficace.

La requête consiste à trouver le nombre maximal de ventes d’un vendeur, du début à la fin de sa promotion.

Cas 1

select salesman.salesmanid, max(sales.quantity)
from salesman
inner join sales  on salesman.salesmanid =sales.salesmanid 
                  and sales.salesdate < salesman.promotiondate
group by salesman.salesmanid 

Cas 2

select salesman.salesmanid, max(sales.quantity)
from salesman
inner join sales  on salesman.salesmanid =sales.salesmanid 
where sales.salesdate < salesman.promotiondate
group by salesman.salesmanid 

Remarque Le cas 1 ne contient pas de clause where.

SGBDR est Sql Server 2005

MODIFIER Si le deuxième élément des critères de jointure ou la clause where était sales.salesdate & Lt; une date fixe pour que ce ne soit pas un critère de joindre les deux tables change la réponse.

Était-ce utile?

La solution

Je ne prendrais pas la performance comme facteur décisif - et très honnêtement, je ne pense pas qu'il y ait de différence de performance mesurable entre ces deux cas, vraiment.

Je voudrais toujours utiliser le cas n ° 2 - pourquoi? Parce que, à mon avis, vous ne devriez mettre que les critères qui établissent la jointure entre les deux tables dans la clause JOIN - tout le reste appartient à la clause WHERE.

Juste une question de garder les choses propres et de mettre les choses à leur place, IMO.

De toute évidence, il existe des cas avec LEFT OUTER JOINs où le placement des critères fait une différence en ce qui concerne les résultats renvoyés - ces cas seraient exclus de ma recommandation, bien sûr.

Marc

Autres conseils

Vous pouvez exécuter l'estimateur de plan d'exécution et le profileur SQL pour voir comment ils se superposent.

Cependant, ils sont sémantiquement identiques sous le capot, conformément à ce MVP SQL Server:

http://www.eggheadcafe.com/conversation .aspx? messageid = 29145383 & amp; threadid = 29145379

Je préfère avoir des critères codés en dur dans la jointure. Cela rend le SQL beaucoup plus lisible et portable.

Lisibilité: Vous pouvez voir exactement quelles données vous obtiendrez, car tous les critères de la table sont écrits là-bas dans la jointure. Dans les grandes déclarations, les critères peuvent être enfouis dans 50 expressions et sont facilement omis.

Portabilité: Vous pouvez simplement copier une partie de la clause FROM et la coller ailleurs. Cela donne les jointures et tous les critères dont vous avez besoin. Si vous utilisez toujours ce critère lorsque vous joignez ces deux tables, le mettre dans la jointure est le plus logique.

Par exemple:

FROM
table1 t1
JOIN table2 t2_ABC ON
  t1.c1 = t2_ABC.c1 AND
  t2_ABC.c2 = 'ABC'

Si vous devez extraire une deuxième colonne du tableau 2, il vous suffit de copier ce bloc dans le Bloc-notes, recherchez / repalce & "ABC &"; et presto et un tout nouveau bloc de code prêt à être collé.

Supplémentaire: Il est également plus facile de passer d'une jointure interne à une jointure externe sans avoir à s'inquiéter des critères susceptibles de flotter dans la clause WHERE.

Je réserve la clause WHERE strictement aux critères d'exécution, dans la mesure du possible.

En ce qui concerne l'efficacité: Si vous parlez de la vitesse d'exécution, comme tout le monde l'a dit, c'est redondant. Si vous parlez de débogage et de réutilisation plus faciles, je préfère l’option 1.

Une chose que je tiens à dire enfin en notifiant, avant cela .. Les deux méthodes peuvent donner les mêmes performances ou utiliser les critères de la clause peut être un peu plus rapide que celle trouvée dans certaines réponses.

Mais j’ai identifié une différence que vous pouvez utiliser pour vos besoins logiques.

  1. L'utilisation des critères de la clause ON ne permet pas de filtrer / ignorer les lignes à sélectionner. Les colonnes de jointure sont nulles en fonction des conditions

  2. Utilisation des critères de la clause peut filtrer / ignorer les lignes de l'ensemble des résultats

Je ne pense pas que vous trouverez une réponse finie pour celui-ci qui s'applique à tous les cas. Les 2 ne sont pas toujours interchangeables car, pour certaines requêtes (certaines jointures à gauche), vous obtiendrez des résultats différents en plaçant les critères dans la ligne WHERE vs la ligne FROM.

Dans votre cas, vous devez évaluer ces deux requêtes. Dans SSMS, vous pouvez afficher les plans d'exécution estimés et réels de ces deux requêtes. Ce serait une première étape utile pour déterminer laquelle est la plus optimale. Vous pouvez également voir l'heure & Amp; IO pour chaque (définir l’heure des statistiques, définir les statistiques sur io) - et cela vous donnera également des informations pour prendre votre décision.

Dans le cas des requêtes de votre question - je parierais qu'elles publieront le même plan de requête -, dans ce cas, cela peut être sans importance, mais dans d'autres cas, cela pourrait éventuellement générer différents plans.

Essayez ceci pour voir la différence entre les 2 ...

SET STATISTICS IO ON
SET STATISTICS TIME ON

select salesman.salesmanid, 
       max(sales.quantity)
from   salesmaninner join sales on salesman.salesmanid =sales.salesmanid
       and sales.salesdate < salesman.promotiondate
group by salesman.salesmanid

select salesman.salesmanid, 
       max(sales.quantity)
from   salesmaninner join sales on salesman.salesmanid = sales.salesmanid 
where  sales.salesdate < salesman.promotiondate
group by salesman.salesmanid

SET STATISTICS TIME OFF
SET STATISTICS IO OFF

Cela peut sembler superficiel, mais la réponse est la requête pour laquelle l’analyseur de requête produit le plan le plus efficace.

À mon avis, ils semblent être équivalents. Par conséquent, l’analyseur de requêtes peut produire des plans identiques, mais vous devrez le tester.

Ni l'un ni l'autre n'est plus efficace, l'utilisation de la méthode WHERE est considérée comme l'ancienne méthode ( http://msdn.microsoft.com/en-us/library/ms190014.aspx ). Vous pouvez consulter le plan d'exécution et constater qu'ils font la même chose.

Familiarisez-vous avec le plan d'exécution estimé dans SQL Management Studio !! Comme d’autres l’ont dit, vous êtes à la merci de l’analyseur, peu importe ce que vous faites, faites donc confiance à ses estimations. Je suppose que les deux que vous avez fournis produiraient exactement le même plan.

Si vous essayez de changer une culture de développement, choisissez celle qui vous donne un meilleur plan. pour ceux qui sont identiques, suivez la culture

J'ai déjà commenté ceci sur d'autres & "Efficacité &"; Des articles comme celui-ci (à la fois sincère et sarcastique) - si c’est là que résident vos goulets d’étranglement, clouez haut pour vous et votre équipe.

Le cas 1 (les critères dans JOIN) est préférable pour l'encapsulation et une encapsulation accrue est généralement une bonne chose: réduction des omissions de copier / coller dans une autre requête, diminution du nombre de bogues si converti ultérieurement en LEFT JOIN et amélioration de la lisibilité (éléments connexes). et moins & "; bruit &"; dans la clause WHERE). Dans ce cas, la clause WHERE ne capture que les critères de table principaux ou les critères couvrant plusieurs tables.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top