2009-04-19 12 views
2

Remarque: Ce ne sont pas des problèmes de devoirs. J'étudie dbms sur mes propres, d'où ces questions de devoirs.Efficient SQL Query

Deux tables:

Teachers (teacher_id, teacher_name) 
Courses (teacher_id,course_id, course_name) 

Pour sélectionner les noms des enseignants qui ne sont pas enseignent des cours, il y a deux questions que je peux penser:

mysql> explain select teacher_name from teachers left join courses on (teachers. 
teacher_id = courses.teacher_id) where course_id is null; 

mysql> explain select teacher_name from teachers where teacher_id not in (select 
teacher_id from courses); 

Lequel sera plus efficace ? Pourquoi?

+0

Vous devez ajouter un TeacherID à la table Courses. –

Répondre

-2

Je recommanderais une 3ème option - et c'est d'ajouter une clause distincte à votre 2ème option et essayer.

Je voterais pour la 2ème option comme étant plus efficace (en particulier avec la clause distincte ajoutée). Vous avez, espérons-le, ajouté un index sur teacher_id dans les deux tableaux. Je viens de remarquer que c'est une question piège - il n'y a pas de champ teacher_id dans Courses.

Si plus d'un enseignant peut enseigner un cours - ajoutez une table Teacher_Course (j'évite toujours les pluriels dans les noms d'objets - juste une pratique). Dans cette nouvelle table, stockez TeacherCourseId (ID généré par le système), ID_surseur et ID_enseignant, et vous pouvez autoriser plus d'un enseignant par classe.

0

Je pense que les sous-requêtes (deuxième option dans votre cas) pourrait courir plus vite parce qu'ils limitent la quantité de lignes retournées et aussi la quantité de colonnes retournées. La première option de la jointure externe gauche peut être plus lente et plus gourmande en mémoire. Mais encore une fois, cela peut dépendre de plusieurs autres facteurs comme le nombre de lignes retournées, les index sur les colonnes, etc.

0

Lequel sera le plus efficace?

Comme toujours: cela dépend de ce qui se trouve dans les tables et de ce qui est indexé.

Habituellement et par défaut, la jointure est préférable à la sous-requête. Il regarde chaque enseignant, puis va directement à la table des cours pour trouver une correspondance pour le teacher_id. J'espère que vous aurez créé un index sur 'Courses.teacher_id' et ce sera une recherche trivialement simple. Mais si ce n'est pas le cas, la sous-requête peut être plus rapide. Si vous avez beaucoup de cours enseignés par relativement peu d'enseignants, cela fera une fois le scan de la table pour générer une petite table temporaire qui pourrait alors être plus rapide à vérifier par rapport à chaque ligne de la table des professeurs.

Mais dans ce cas, il serait probablement préférable de simplement ajouter l'index à la place.