#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
, у вас также может быть (или не нужен) индекс.