147 votes

Jointures SQL Vs sous-requêtes SQL (Performance)?

Je souhaite savoir si j'ai une jointure requête à quelque chose comme ça -

Select E.Id,E.Name from Employee E join Dept D on E.DeptId=D.Id

et une sous-requête à quelque chose comme ça -

Select E.Id,E.Name from Employee Where DeptId in (Select Id from Dept)

Quand je considère les performances lequel des deux requêtes serait plus rapide et why ?

Aussi est-il un moment où je préférerais l'un sur l'autre ?

Désolé si ce est trop banal et a demandé avant, mais je suis confus à ce sujet. Aussi, il serait excellent si vous les gars, vous pouvez me suggérer des outils que je devrais utiliser pour mesurer la performance des deux requêtes. Merci beaucoup!

59voto

linuxatico Points 533

Eh bien, je pense que c'est un "Vieil Or" de la question. La réponse est: "Ça dépend!". Les performances sont un sujet aussi délicat que ce serait trop bête à dire: "ne Jamais utiliser des sous-requêtes, toujours joindre". Dans les liens suivants, vous trouverez quelques-unes de base, les meilleures pratiques que j'ai trouvé pour être très utile: Ici 1 Ici 2 Ici 3

J'ai une table avec 50000 éléments, le résultat que je cherchais 739 éléments.

Ma requête était d'abord ceci:

SELECT  p.id,
    p.fixedId,
    p.azienda_id,
    p.categoria_id,
    p.linea,
    p.tipo,
    p.nome
FROM prodotto p
WHERE p.azienda_id = 2699 AND p.anno = (
    SELECT MAX(p2.anno) 
    FROM prodotto p2 
    WHERE p2.fixedId = p.fixedId 
)

et il a fallu 7,9 s pour l'exécuter.

Ma question est ceci:

SELECT  p.id,
    p.fixedId,
    p.azienda_id,
    p.categoria_id,
    p.linea,
    p.tipo,
    p.nome
FROM prodotto p
WHERE p.azienda_id = 2699 AND (p.fixedId, p.anno) IN
(
    SELECT p2.fixedId, MAX(p2.anno)
    FROM prodotto p2
    WHERE p.azienda_id = p2.azienda_id
    GROUP BY p2.fixedId
)

et il a fallu 0.0256 s

Bonne SQL, bon.

57voto

JNK Points 32743

J'attendrais la première requête pour être plus rapide, principalement parce que vous avez une équivalence et explicite REJOINDRE. Dans mon expérience, IN est un processus très lent de l'opérateur, depuis SQL normalement évalue comme une série d' WHERE clauses séparées par "OU" (WHERE x=Y OR x=Z OR...).

Comme avec TOUTES les CHOSES SQL cependant, votre kilométrage peut varier. La vitesse dépendra beaucoup sur les index (avez-vous des indices sur ID colonnes? Qui va aider beaucoup...), parmi d'autres choses.

La seule VÉRITABLE façon de savoir avec certitude à 100% ce qui est plus rapide est de se tourner sur le suivi des performances (IO Statistiques est particulièrement utile) et de les exécuter à la fois. Assurez-vous de vider votre cache entre les courses!

11voto

HLGEM Points 54641

Commencer à regarder les plans d'exécution pour voir les différences dans la façon dont SQl Server va les interpréter. Vous pouvez également utiliser le Profiler pour exécuter les requêtes multiples fois et obtenir la differnce.

Je ne voudrais pas que ces être si horrible, où vous pouvez obtenir réel, de grands gains de performance en utilisant des jointures au lieu de sous-requêtes est lorsque vous utilisez des sous-requêtes corrélées.

EXISTE est souvent meilleure que l'autre de ces deux et quand vous parlez de la gauche se joint à l'endroit où vous voulez tous les documents ne sont pas dans la gauche de la table de jointure, puis n'EXISTE PAS est souvent un bien meilleur choix.

6voto

Lucero Points 38928

La performance devrait être le même, c'est bien plus important d'avoir le bon index et l'agrégation est appliquée sur vos tables (il existe quelques bonnes ressources sur le sujet).

(Modifié afin de refléter la mise à jour de question)

5voto

onedaywhen Points 24594

Les deux requêtes ne peuvent pas être sémantiquement équivalentes. Si un employé travaille pour plus d'un ministère (possible dans l'entreprise, je travaille pour l'; certes, cela impliquerait que votre tableau n'est pas complètement normalisée) puis la première requête retourne des lignes en double alors que la deuxième requête ne serait pas. Pour faire les requêtes d'équivalent dans ce cas, l' DISTINCT mot-clé devrait être ajouté à l' SELECT de la clause, ce qui peut avoir un impact sur les performances.

Remarque il existe une conception de la règle qui dit qu'un tableau doit modèle entité/classe ou d'une relation entre entités/classes mais pas les deux. Par conséquent, je vous suggère de créer une troisième table, dire OrgChart, pour modéliser la relation entre les employés et les départements.

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