Я пытаюсь объяснить свою проблему примерами. Я с тех пор работает оператор вродеLarge UPDATE [...] SELECT FROM вызывает параллельное UPDATE/DELETE, чтобы умереть
UPDATE <table_A>
INNER JOIN <table_B> ON [...]
LEFT JOIN <table_C> ON [...]
LEFT JOIN <table_D> ON [...]
LEFT JOIN <table_E> ON [...]
SET <table_A>.<col_A>=X
WHERE <table_A>.<col_A>=Y AND COALESCE(<table_C>.<id>,<table_D>.<id>,<table_E>.<id> IS NULL
Это утверждение работает на больших таблиц (два из них содержат 7+ миллиона строк в таблице). Обновление выполняется 3-5 минут. В другой сессии там делается в высокой параллельности
UPDATE <table_C> SET <col_A>=Z WHERE <id> IN ([...])
или
DELETE FROM <table_C> WHERE <id> IN ([...])
Когда большие UPDATE
работает, то они одновременно UPDATE
и DELETES
умереть с тайм-аут или ожидания блокировки тупиков после одной или двух минут. Все столбцы JOIN
индексируются (стандартные индексы). Я уже пытался сделать
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
[BIG UPDATE];
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
, но это не помогает. Консистенция данных на <table_A>
не так важна (это не проблема, если она содержит строки, которые не существуют в <table_C>
... <table_E>
). Самое главное, что обрабатываются мелкие UPDATE
/DELETE
с на <table_C>
... <table_E>
.
Как правило, это не очень хорошая идея сделать такие большие обновления в живой базе данных. Например, вы можете разбить свое большое обновление на несколько меньших. – Anri
Это не вариант для меня, потому что я должен знать, что «product_id» должен быть ни в одной из таблиц '' ... ''. Я уже пробовал ваше предложение, но самая большая таблица из них содержит 7+ миллионов строк, и этого достаточно, чтобы вызвать тайм-ауты блокировки (независимо от того, были ли другие две таблицы также «JOIN'ed) –
rabudde
Проверьте, есть ли мой ответ в отличие от того, что вы пробовали. – Anri