Y a-t-il des différences de performance ou de fonctionnalité entre ces deux instructions SQL?

Je suis en train de maintenir le SQL de quelqu'un d'autre en ce moment, et je suis tombé sur ceci dans une procédure stockée:

SELECT Location.ID, Location.Location, COUNT(Person.ID) As CountAdultMales FROM Transactions INNER JOIN Location ON Transactions.FKLocationID = Location.ID INNER JOIN Person ON Transactions.FKPersonID = Person.ID AND DATEDIFF(YEAR, Person.DateOfBirth, GETDATE()) >= 18 AND Person.Gender = 1 WHERE ((Transactions.Deleted = 0) AND (Person.Deleted = 0) AND (Location.Deleted = 0)) 

Y a-t-il une différence entre ce qui précède et ceci (qui est comment je l'écrirais)

 SELECT Location.ID, Location.Location, COUNT(Person.ID) As CountAdultMales FROM Transactions INNER JOIN Location ON Transactions.FKLocationID = Location.ID INNER JOIN Person ON Transactions.FKPersonID = Person.ID WHERE ((Transactions.Deleted = 0) AND (Person.Deleted = 0) AND (Location.Deleted = 0) AND (DATEDIFF(YEAR, Person.DateOfBirth, GETDATE()) >= 18) AND (Person.Gender = 1)) 

Personnellement, je trouve que les conditions de la clause WHERE sont plus lisibles, mais je me demandais s'il y avait des performances ou d'autres raisons pour «conditionner» (s'il y a un tel mot) le JOIN

Merci

La performance est la même dans vos exemples, mais vous pouvez l'accorder de cette façon:

 SELECT Location.ID, Location.Location, COUNT(Person.ID) As CountAdultMales FROM Transactions INNER JOIN Location ON Transactions.FKLocationID = Location.ID INNER JOIN Person ON Transactions.FKPersonID = Person.ID WHERE Transactions.Deleted = 0 AND Person.Deleted = 0 AND Location.Deleted = 0 AND Person.DateOfBirth < dateadd(year, datediff(year, 0, getdate())-17, 0) AND Person.Gender = 1 

De cette façon, vous ne faites pas de calcul sur toutes les colonnes pour get l'année. Au lieu de cela, vous comparerez simplement l'année avec une valeur statique beaucoup plus rapide.

Cette requête sélectionne les lignes où les personnes atteignent 18 ans (ou sont plus âgées) avant la fin de l'année en cours.

Avec une inner join cela ne fera pas vraiment de différence puisque SQL dispose d'un optimiseur de requêtes qui fera de son mieux pour exécuter la requête de la manière la plus efficace possible (pas parfaite).

S'il s'agissait d'une outer join cela pourrait faire une différence, alors c'est quelque chose à savoir

Les performances de la requête sont identiques. Il n'y a pas de différence pour la jointure interne.

Ne vous inquiétez pas du plan exec ici, comme les membres du SO l'ont déjà dit, ils devraient produire un plan exec identique. Autant à propos de la question elle-même.

Vous devriez vous soucier de la lisibilité du code et du maintien s'il est trop tôt ou s'il y a peu ou pas d'optimization possible.

Est-ce que ce devrait être un critère de jointure ou un filter? En regardant le code lui-même, je pense que cela fait partie du filter.

Cela dépend de la database avec laquelle vous travaillez. En général, l'optimiseur interne de DB va régler cela.

Veuillez jeter un oeil ici: INNER JOIN ON vs WHERE clause