Запрос обновления MySQL, где в подзапросе медленно

#mysql #performance #sql-update #subquery #where-in

#mysql #Производительность #sql-обновление #подзапрос #где-в

Вопрос:

У меня возникли проблемы с тем, что запрос MySQL выполняется очень медленно. Для обработки каждого ОБНОВЛЕНИЯ требуется около 2 минут.

Это запрос:

    UPDATE msn
   SET is_disable = 1
   WHERE mid IN
   (
       SELECT mid from link
       WHERE rid = ${param.rid}
   );
  

Итак, мой вопрос в том, что я хотел бы знать, как повлияет на производительность инструкции UPDATE, если результат подзапроса равен 0 или НУЛЮ. Потому что я думаю, что, возможно, процесс идет медленно, потому что результат подзапроса равен 0 или НУЛЮ.

Заранее большое спасибо.

Комментарии:

1. Проверьте «мультитаблицу» UPDATE .

2. @Rick спасибо, я проверю это, и я хотел бы знать, повлияет ли производительность запроса, если результат подзапроса равен 0 или НУЛЮ.

3.Есть mid NULLable ? Может ли это быть 0? Эти вопросы относятся к обеим таблицам. (То есть в вашем «простом» вопросе может быть 4 комбинации значений, скрытых.) IN (SELECT ...) используется для ужасной работы; какую версию MySQL вы используете?

4. Обнуляется для таблицы ссылок и не обнуляется для таблицы msn. Я использую mysql 5.7.25. если результатом моего подзапроса не является ничего или вообще нет строки, означает ли это, что предложение WHERE в запросе стало таким: WHERE mid = «»; ?

5. Можете ли вы предоставить план выполнения?

Ответ №1:

Проблема здесь в том, что следующий подзапрос IN должен выполняться независимо от того, возвращает он какие-либо записи или нет. Я бы, вероятно, выразил ваше обновление, используя логику exists:

 UPDATE msn m
SET is_disable = 1
WHERE EXISTS (SELECT 1 FROM link l WHERE m.mid = l.mid AND l.rid = ${param.rid});
  

Затем добавьте следующий индекс в link таблицу:

 CREATE INDEX idx ON link (mid, rid);
  

Вы также можете попробовать и сравнить с этой версией индекса:

 CREATE INDEX idx ON link (rid, mid);
  

Комментарии:

1. Привет, Тим! Спасибо за ответ. Есть ли какое-либо странное поведение, если результат подзапроса равен 0 или НУЛЮ?

2. «Стоимость» подзапроса — это то, сколько времени требуется MySQL, чтобы утверждать, что он может или не может найти соответствующее mid значение. В худшем случае link пришлось бы сканировать всю таблицу (или нужно было бы сканировать эквивалентный индекс). В случае, когда link таблица полностью пуста, этот поиск завершится очень быстро.