2009-04-19 11 views
2

Hinweis: Dies sind keine Hausaufgabenprobleme. Ich studiere dbms auf eigene Faust, daher diese Hausaufgaben-ähnliche Fragen.Effiziente SQL-Abfrage

Zwei Tische:

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

Um Lehrer Namen zu wählen, der keine Kurse lehren, gibt es zwei Abfragen ich mir vorstellen kann:

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

Welches effizienter sein wird ? Warum?

+0

Sie müssen der Tabelle Courses eine TeacherID hinzufügen. –

Antwort

-2

Ich würde eine dritte Option empfehlen - und das ist eine eindeutige Klausel zu Ihrer zweiten Option hinzufügen und geben Sie das.

Ich würde für die zweite Option als effizienter wählen (vor allem mit der eindeutigen Klausel hinzugefügt). Sie haben hoffentlich in beiden Tabellen einen Index für teacher_id hinzugefügt.

Bearbeiten:
Ich habe gerade festgestellt, es ist eine Frage Trick - es gibt keine Lehrer_id Feld in Kurse.

Wenn mehr als ein Lehrer einen Kurs unterrichten kann - fügen Sie einen Tisch Teacher_Course hinzu (ich vermeide immer Plural in Objektnamen - nur eine Übung). In dieser neuen Tabelle speichern Sie die TeacherCurseId (systemgenerierte ID), course_id und die Lehrer-ID, und Sie können mehr als einen Lehrer pro Klasse zulassen.

0

Ich denke, dass Unterabfragen (zweite Option in Ihrem Fall) könnte schneller laufen, weil sie die Menge der zurückgegebenen Zeilen und auch die Menge der Spalten zurückgegeben begrenzen. Die erste Option des linken äußeren Joins kann langsamer und speicherintensiver sein. Aber wieder kann es von verschiedenen anderen Faktoren wie der Anzahl der zurückgegebenen Zeilen, Indizes auf Spalten usw. abhängen.

0

Welche wird effizienter sein?

Wie immer: es hängt davon ab, was in den Tabellen steht und was indiziert wird.

Normalerweise und standardmäßig ist der Join der Unterabfrage vorzuziehen. Er betrachtet jeden Lehrer und geht dann direkt zur Kurstabelle, um eine Übereinstimmung für die Lehrer_ID zu finden. Hoffentlich haben Sie einen Index für 'Courses.teacher_id' erstellt und dies wird eine trivial einfache Suche sein.

Aber wenn Sie dies nicht tun, könnte die Unterabfrage schneller sein. Wenn Sie viele Kurse von relativ wenigen Lehrern unterrichten, würde dies die Tabelle einmal scannen, um eine kleine temporäre Tabelle zu generieren, die dann schneller gegen jede Zeile aus der Lehrer-Tabelle überprüft werden kann.

Aber in diesem Fall wäre es wahrscheinlich am besten, nur den Index stattdessen hinzuzufügen.