Почему предложение update занимает много времени, в то время как предложение select (с той же логикой) этого не делает?

#mysql #sql #performance #select #updates

#mysql #sql #Производительность #выберите #Обновления

Вопрос:

Вот select запрос, который выполняется в 0.03 сек:

 select * from engine.transactions 
where transaction_row not in (select transaction_row from d.pos_transactions)
 

Я хочу обновить сопоставленные (выбранные) строки из приведенного выше запроса таким образом:

 update engine.transactions set retry = 0 
where transaction_row not in (select transaction_row from d.pos_transactions)
 

который возвращает timeout ошибку:

#1205 — Превышен тайм-аут ожидания блокировки; попробуйте перезапустить транзакцию

Почему производительность так сильно падает update в предложении on?


Отмечено, что в таблице есть только один индекс engine.transactions : transactions(psp_id, transaction_row) .

Кроме того, механизм таблиц InnoDB

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

1. Перепишите WHERE NOT IN (что в большинстве случаев происходит медленно) на WHERE NOT EXISTS или JOIN WHERE РАВНО NULL .

2. Сколько записей необходимо обновить? Может быть проблема с блокировкой. Самая глупая вещь, которую я сам когда-то делал, — это две работы в двух сеансах и блокировка …, ибп, замедление ввода

Ответ №1:

Я бы рекомендовал написать запрос следующим образом:

 update engine.transactions t left join
       d.pos_transactions pt
       using (transaction_row)
    set retry = 0 
    where pt.transaction_row is null;
 

Для повышения производительности вам нужен индекс d.post_transactions(transaction_row) . Однако, учитывая производительность select , у вас также может быть (или не нужен) индекс.