2013-07-23 5 views
3

Je maintiens de quelqu'un d'autre SQL pour le moment, et je suis tombé sur ceci dans une procédure stockée:Y a-t-il une différence de performance ou de fonctionnalité entre ces deux instructions SQL?

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)) 

est-il une différence entre ce qui précède et ce (ce qui est la façon dont je l'écrire)

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 mettre les conditions de la clause WHERE plus lisible, mais je me demandais s'il y avait des performances ou d'autres raisons de « conditionalise » (s'il y a un tel mot) la REJOIGNEZ

Merci

+0

Sur mon SQL Server 2008R2, les plans d'exécution générés sont identiques. – jpw

+2

Ne pas oublier d'accepter les réponses, également sur vos autres questions –

+0

Je vais, t-clausen.dk, lorsque les questions sont traitées! – Edwardo

Répondre

2

Performance est le même dans vos exemples, mais vous pouvez le régler 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 un calcul sur toutes les colonnes pour obtenir 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 dans lesquelles les personnes atteignent l'âge de 18 ans (ou plus) avant la fin de l'année en cours.

3

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

Si tel était un outer join il pourrait faire une différence que si ses quelque chose d'être conscient de

3

la performance est à la fois la requête est le même. Il n'y a pas de différence pour la jointure interne.

2

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

Vous devez vous soucier de la lisibilité du code et de la maintenance s'il est trop tôt ou s'il y a peu d'optimisation possible.

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

Questions connexes