1

J'ai deux tables appelées Employee (colonnes: Id, Name) et DataSource (colonnes: Id, EmployeeId, DataSourceName).Recherche de lignes du tableau A sans enregistrement dans la table jointe B

Chaque employé peut être exporté vers zéro ou plusieurs sources de données et d'imaginer situation suivante:

table des employés

+----+-------------+ 
| Id | Name  | 
+----+-------------+ 
| 1 | Ivan  | 
| 2 | Adam  | 
+----+-------------+ 

table DataSource:

+----+---------------------------------+ 
| Id | EmplpoyeeId | DataSourceName | 
+----+---------------------------------+ 
| 1 | 1    | Source1   | 
| 2 | 1    | Source2   | 
| 3 | 2    | Source2   | 
+----+---------------------------------+ 

je besoin d'une requête pour déterminer quel employé n'est pas exporté vers 'Source1' (le résultat devrait être 'Adam' dans ce cas car il est exporté vers 'Source2' uniquement). Tableaux Employee et DataSource peuvent avoir une grande quantité d'enregistrements (en milliers).

Il existe quelques techniques pour le déterminer et nous devons trouver celui avec les meilleures performances. Il y a peu, qui est venu à mon esprit:

gauche JOIN:

SELECT Employee.Id 
FROM Employee 
LEFT JOIN DataSource ON DataSource.EmployeeId = Employee.Id AND DataSource.DataSourceName = 'Source1' 
WHERE DataSource.Id IS NULL 

INNER SELECT:

SELECT Employee.Id 
FROM Employee 
WHERE NOT EXIST (SELECT NULL FROM DataSource WHERE DataSource.EmployeeId = Employee.Id AND DataSource.DataSourceName = 'Source1') 

EXCEPTION:

SELECT Employee.ID 
FROM Employee 

EXCEPT 

SELECT Employee.Id 
FROM Employee 
INNER JOIN DataSource ON DataSource.EmployeeId = Employee.Id AND DataSource.DataSourceName = 'Source1' 

Avant de commencer les analyses comparatives J'aimerais pour me demander s'il y a plus de moyens que je devrais prendre en compte (et qui pourraient bien fonctionner). Pourriez-vous s'il vous plaît partager vos idées pour la requête la plus performante.

+0

Vous devez simplement tester, mais le WHERE NOT EXISTS "devrait" être plus rapide, car il n'a pas besoin de faire la jointure complète et peut sortir tôt ... mais cela dépendra d'un certain nombre de facteurs dont vous avez vraiment besoin juste pour tester – Milney

+0

Je pense que oui, nous pouvons également quitter après la première inscription (en utilisant SELECT TOP 1) - cela pourrait aussi jouer pour WHERE NOT EXISTS – jabko87

+0

Si vous utilisez un select dans un NOT EXIST(), vous n'avez pas besoin pour utiliser TOP 1, il s'arrêtera automatiquement après avoir trouvé un enregistrement – Milney

Répondre

1

Si vous avez besoin de plus de lecture sur le sujet cet article est bon;

http://www.sqlinthewild.co.za/index.php/2010/03/23/left-outer-join-vs-not-exists/

Il suggère que le PAS EXISTE interprétera mieux, car il n'a pas besoin de remplir tout le rejoindre (fait un Anti-Semi rejoindre la place d'un semi Inscrivez-vous);

"C'est la principale différence entre ces deux méthodes: lors de l'utilisation de la technique LEFT OUTER JOIN ... IS NULL, SQL ne peut pas dire que vous ne faites que vérifier l'absence de l'optimiseur. fait la jointure complète puis filtre les filtres NOT EXISTS dans le cadre de la jointure. "

+0

Milney Je m'interroge également sur la 3ème option - exception, je l'ai ajouté à ma question. Que penses-tu de celui-ci? – jabko87

+0

@ jabko87 - Ceci est en fait logiquement différent - par exemple, EXCEPT filtrera les doublons (comme si vous aviez appliqué DISTINCT) car il s'agit d'une opération basée sur un ensemble, il traitera également les valeurs NULL si vous les avez.Donc vous pouvez utiliser sauf mais devrez considérer si c'est en fait la même chose .. Je ne pense pas que ce sera plus rapide cependant (car encore une fois - il doit traiter l'ensemble des résultats) donc j'irais avec NOT EXISTS . Mais la seule façon de savoir à coup sûr (avec votre profil de données spécifique) est de TEST! Il suffit de lancer les deux fois, et de mesurer la différence (utilisez SET STATISTICS TIME ON) – Milney

+0

@ jabko87 La chose la plus importante pour la performance sera d'avoir un INDEX sur les colonnes (EmployeeId et DataSourceName) avec des statistiques à jour ... Si vous avoir cela, ils devraient tous effectuer de façon acceptable – Milney