Les critères de filtre SQL dans les critères de jointure ou là où la clause est plus efficace

j'ai une requête relativement simple reliant deux tables. Les critères " où "peuvent être exprimés soit dans les critères join ou sous forme de clause "où". Je me demande qui est plus efficace.

requête est de trouver max ventes pour un vendeur du début des temps jusqu'à ce qu'ils ont été promus.

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: Cas 1 manque une clause where complètement

RDBMS is Sql Server 2005

EDIT Si le deuxième élément des critères d'adhésion ou de la clause où étaient les ventes.date de vente < une date fixe de sorte que ce n'est pas en fait un critère de rejoindre les deux tableaux fait que changer la réponse.

22
demandé sur Gratzy 2009-09-10 00:26:06

9 réponses

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

j'utiliserais toujours le cas #2-Pourquoi? Parce que, à mon avis, vous devriez seulement mettre les critères réels qui établissent la jointure entre les deux tables dans la clause de jointure - tout le reste appartient à la clause où.

il suffit de garder les choses propres et de les mettre à leur place, OMI.

évidemment, il y a des cas avec jointures externes gauches où l'emplacement des critères fait une différence en termes de résultats obtenir retourné - ces cas seraient exclus de ma recommandation, bien sûr.

Marc

22
répondu marc_s 2009-09-09 20:41:02

vous pouvez exécuter l'estimateur de plan d'exécution et le profileur sql pour voir comment ils s'empilent l'un contre l'autre.

cependant, ils sont sémantiquement les mêmes sous le capot selon ce serveur SQL MVP:

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

3
répondu klabranche 2009-09-09 20:36:43

je préfère avoir tout codé en dur critères dans la jointure. Il rend le SQL beaucoup plus lisible et portable.

Lisibilité: Vous pouvez voir exactement quelles données vous allez obtenir parce que tous les critères de table sont écrits là dans la jointure. Dans les grands énoncés, les critères peuvent être enfouis dans 50 autres expressions et sont facilement oubliés.

Portabilité: Vous pouvez simplement copier un morceau de la clause de et le coller ailleurs. Qui donne les jointures et tout les critères que vous avez besoin pour aller avec elle. Si vous utilisez toujours ce critère en joignant ces deux tables, alors 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 avez besoin d'obtenir une deuxième colonne du tableau 2, vous n'avez qu'à copier ce bloc dans Notepad, search/repalce "ABC" et presto et tout le nouveau bloc de code prêt à coller en arrière.

supplémentaire: Il est également plus facile de passer d'une jointure intérieure à une jointure extérieure sans avoir à se soucier de les critères qui peuvent flotter dans la clause "où".

je réserve la clause WHERE strictement pour les critères d'exécution lorsque c'est possible.

en ce qui concerne l'efficacité: Si vous faites référence à la vitesse d'excécution, alors comme tout le monde l'a dit, c'est redondant. Si vous faites référence à un débogage et une réutilisation plus faciles, alors je préfère l'option 1.

3
répondu Spencer Evans 2013-06-06 02:08:35

je ne pense pas que vous trouverez une réponse partielle pour ce 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 où vs LA LIGNE DE FROM.

Dans votre cas, vous devez évaluer ces deux requêtes. Dans le SSMS, vous pouvez voir les plans d'exécution estimés et réels de ces deux requêtes - ce serait une bonne première étape pour déterminer ce qui est plus optimal. Vous pouvez également afficher l'heure et IO pour chaque (ensemble des statistiques en temps, des statistiques io) - et qui vous donnera également des informations pour prendre votre décision.

dans le cas des requêtes dans votre question - je parierais qu'ils sortiront tous les deux avec le même plan de requête - donc dans ce cas, cela peut ne pas avoir d'importance, mais dans d'autres, cela pourrait potentiellement produire des plans différents.

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
1
répondu Scott Ivey 2009-09-09 20:33:49

une chose que je veux dire finalement comme je l'ai notifié, avant cela.. Les deux façons peuvent donner la même performance ou en utilisant les critères à clause peut être un peu plus rapide comme trouvé dans certaines réponses..

Mais j'ai identifié une différence, vous pouvez utiliser votre logique besoins..

  1. en Utilisant les critères à clause ne filtrera pas / ne sautera pas les lignes pour sélectionner à la place les colonnes de jointure seraient nulles basé sur le conditions

  2. en Utilisant les critères à de la clause de filtre/sauter les lignes au niveau de l'ensemble des résultats

1
répondu Michael Rajesh 2017-03-02 09:52:51

cela peut sembler désinvolte, mais la réponse est n'importe quelle requête pour laquelle l'analyseur de requête produit le plan le plus efficace.

à mon avis, ils semblent être équivalents, donc l'analyseur de requête peut bien produire des plans identiques, mais vous devriez tester.

0
répondu Craig Shearer 2009-09-09 20:30:12

ni L'un ni l'autre n'est plus efficace, en utilisant la méthode où est considéré comme l'ancienne façon de le faire (http://msdn.microsoft.com/en-us/library/ms190014.aspx). Vous pouvez regarder le plan d'exécution et voir qu'ils font la même chose.

0
répondu Bryan S. 2009-09-09 20:31:09

familiarisez-vous avec le plan D'exécution estimé dans le studio de gestion SQL!! Comme d'autres l'ont dit, Vous êtes à la merci de l'analyseur quoi que vous fassiez, faites confiance à ses estimations. Je suppose que les deux que vous avez fourni produiraient le même plan.

si c'est une tentative 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 commenté ceci sur d'autres Billets" efficiency " comme celui-ci (il est à la fois sincère et sarcastique) -- si c'est là où vos goulots d'étranglement résident, alors high-five pour vous et votre équipe.

0
répondu Austin Salonen 2009-09-09 20:46:48

Cas 1 (critères dans la jointure) est mieux pour l'encapsulation, et l'augmentation de l'encapsulation est généralement une bonne chose: diminution de copier/coller des omissions à une autre requête, diminution des bogues si plus tard converti en jointure gauche, et une lisibilité accrue (choses liées ensemble et moins de "bruit" dans la clause WHERE). Dans ce cas, la clause "WHERE" ne s'applique qu'aux principaux critères ou critères de la table qui couvrent plusieurs tables.

0
répondu Pete Alvin 2017-04-13 13:54:42