2016-04-27 8 views
3

Diese Abfrage wird langsam ausgeführt und wird langsamer, wenn die Tabelle wächst. Kann jemand einen Weg finden, die Geschwindigkeit zu erhöhen?Erhöhen Sie die Geschwindigkeit der Unterabfrage

Es ist beabsichtigt, tblUser_Lesson mit IDs von tblUser und tblLesson zu füllen, während sichergestellt wird, dass die IDs in der Tabelle vor dem Einfügen nicht vorhanden sind.

Ich habe einen Index auf tblUser.name und tblLesson.name, aber es scheint keinen Unterschied zu machen.

INSERT INTO tblUser_Lesson (user, lesson) 
    SELECT userId, lessonId 
    FROM 
    (
     SELECT tblUser.id userId, tblLesson.id lessonId 
     FROM tblUser, 
      tblLesson 
     WHERE tblUser.name=? 
     AND tblLesson.name=? 
) tmp 
    WHERE NOT EXISTS (SELECT user 
        FROM tblUser_Lesson tmp1 
        WHERE tmp1.user = tmp.userId 
         AND tmp1.lesson = tmp.tblLesson) 
+0

Kein JOIN-Zustand? Sehr unerwartet. – jarlh

+0

Einfaches JOIN würde es um Meilen beschleunigen ... – Veljko89

+1

Was genau versuchen Sie mit diesem 'INSERT' zu erreichen? –

Antwort

6

Dies ist eine gleichwertige Version der Abfrage, die ich leichter finden zu lesen:

INSERT INTO tblUser_Lesson(user, lesson) 
    SELECT userId, lessonId 
    FROM tblUser u CROSS JOIN 
     tblLesson l 
    WHERE u.name = ? AND l.name = ? AND 
      NOT EXISTS (SELECT 1 
         FROM tblUser_Lesson ul 
         WHERE ul.user = u.userId AND ul.lesson = l.tblLesson 
        ); 

Meine erste Empfehlung ist die Datenbank zu lassen, die Arbeit zu tun. Erstellen Sie einen eindeutigen Index für tblUser_Lesson:

create unique index unq_tblUser_Lesson on tblUser_Lesson(UserId, Lesson); 

Dann tun, nur um den Einsatz als:

INSERT INTO tblUser_Lesson(user, lesson) 
    SELECT userId, lessonId 
    FROM tblUser u CROSS JOIN 
     tblLesson l 
    WHERE u.name = ? AND l.name = ? ; 

Zweitens würde ich Indizes für jede der anderen Tabellen erstellen:

create index idx_tbluser_name_id on tblUser(name, id); 
create index idx_tblLesson_name_id on tblLesson(name, id); 

Das beschleunigt diese Abfrage.

Wenn Sie (im Allgemeinen) bei einem Duplikat keinen Fehler erhalten möchten, können Sie Ihre NOT EXISTS-Klausel an ihrem Platz lassen. Der Index auf tblUser_Lesson wird immer noch helfen.

+2

Große Erklärung, ich mag es – Veljko89

+0

Sie haben es @Gordon genagelt. Gute Antwort. Ich habe die Abfragesyntax verbessert und die Insert-Geschwindigkeit reduziert. Vielen Dank!! – Ninja3412