2016-04-27 4 views
3

Этот запрос выполняется медленно и замедляется по мере роста таблицы. Может ли кто-нибудь найти способ увеличить скорость?Увеличение скорости подзапроса

Предполагается заполнить tblUser_Lesson идентификаторами tblUser и tblLesson, гарантируя, что идентификаторы не существуют в таблице перед вставкой.

У меня есть указатель на tblUser.name и tblLesson.name, но это, похоже, не имеет значения.

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

Нет JOIN состояние? Очень неожиданно. – jarlh

+0

Простой JOIN ускорит его на миллион ... – Veljko89

+1

Что именно вы пытаетесь выполнить с помощью этого 'INSERT'? –

ответ

6

Это эквивалентно вариант запроса, который я нахожу легче читать:

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

Моя первая рекомендация, чтобы база данных сделать работу. Создать уникальный индекс на tblUser_Lesson:

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

Тогда просто сделать вставку как:

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

Во-вторых, я хотел бы создать индексы для каждого из других таблиц:

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

Это ускоряет этот запрос.

Если вы (в общем) не хотите получать сообщение об ошибке при наличии дубликата, то вы можете оставить свой пункт NOT EXISTS на месте. Индекс на tblUser_Lesson по-прежнему поможет.

+2

Отличное объяснение, мне нравится – Veljko89

+0

Вы пригвоздили его @ Gordon. Отличный ответ. Я улучшил синтаксис запроса и сократил скорость вставки. Благодаря!! – Ninja3412