Выполнение запроса занимает слишком много времени

В настоящее время у меня есть две таблицы в базе данных. Вызываемая электронная почта и отписавшиеся от подписки в обеих таблицах имеют столбец с именем Электронная почта. теперь я хочу сравнить эти две таблицы, и везде, где совпадает электронная почта, я хочу обновить столбец в таблице электронной почты с именем Email_status_id до 2... запрос, который я использую,

UPDATE  Email E
SET E.Email_status_id = 2
WHERE 
    E.Email
  IN (
    SELECT 
     U.Email
    FROM 
     UNSUSCRIBED U);

В настоящее время я использую mysql.

таблица электронной почты имеет 2704569 строк электронной почты, а таблица неподписанных содержит 12102 строки электронной почты.

время выполнения запроса длится вечно....

любое предложение по сокращению времени выполнения запроса...


person mb1987    schedule 31.07.2014    source источник
comment
DBA может быть лучшим местом для этого, но в любом случае никакая оценка не может быть выполнена без показа схемы таблицы.   -  person crthompson    schedule 01.08.2014
comment
У вас есть индекс в столбце Email.Email?   -  person Albin Sunnanbo    schedule 01.08.2014
comment
Нужно больше информации. Индексы? Кроме того, я не думаю, что это вопрос DBA. Это просто настройка запроса/индекса. Если у вас нет индексов для поля Email в обеих этих таблицах, это было бы ОТЛИЧНЫМ местом для начала.   -  person Kris Gruttemeyer    schedule 01.08.2014


Ответы (3)


Первым делом нужно создать индекс для Unsubscribed(Email):

create index idx_unsubscribed_email on unsubscribed(email);

Или, что еще лучше, объявите его как primary key, особенно если это единственный столбец в таблице.

Затем MySQL иногда плохо справляется с реализацией in. Существует множество способов написать запрос с использованием индекса. Exists — типичный метод:

update email e
     set email_status_id = 2
     where exists (select 1 from unsubscribed u where u.email = e.email);

Версия join должна иметь аналогичную производительность с индексом.

РЕДАКТИРОВАТЬ:

Индекс email(email) также может помочь в этом запросе. Я почему-то предполагал, что это уже будет ключ в таблице.

person Gordon Linoff    schedule 31.07.2014
comment
большое спасибо, это сработало... Время выполнения запроса значительно сократилось - person mb1987; 01.08.2014

Вы выполняете сравнение строк по большому количеству данных в предложении In. Поскольку вам на самом деле не нужны возвращаемые данные, вы можете сделать это в Exists:

Update  Email E
Set     E.Email_status_id = 2
Where Exists
(
    Select  1
    From    Unsubscribed    U
    Where   U.Email = E.Email
)

Кроме того, правильная индексация столбца Email в обе таблицы Email и Unsubscribed также повысят вашу производительность.

person Siyual    schedule 31.07.2014

Операторы IN для целых таблиц обычно медленны. Это связано с тем, что он должен запускать ваш подзапрос для каждой строки в таблице, чтобы получить отфильтрованный набор результатов. Вместо этого попробуйте использовать объединение, например:

Update Unsubscribed U join Email E on E.Email=U.Email
SET E.email_status_id = 2
person Elk    schedule 31.07.2014