Я выполняю параллельные запросы Postgres, например:
UPDATE foo SET bar = bar + 1 WHERE baz = 1234
Каждый запрос влияет на фиксированное число строк K, и я не могу найти способ обеспечить порядок, в котором строки обновляются, я получаю взаимоблокировки. В настоящее время я исправляю проблему, применяя порядок вручную, но это означает, что мне нужно выполнить гораздо больше запросов, чем обычно, одновременно увеличивая сложность поиска с O (log N + K) до O (K log N).
Есть ли способ улучшить производительность, не оказываясь уязвимым для тупиков? Я подозреваю, что замена (baz)
индекса на (baz, id)
индекс может сработать при условии, что Postgres обновляет строки в том же порядке, в котором они их сканировали. Стоит ли придерживаться такого подхода?
postgresql
locking
deadlock
update
Алексей Аверченко
источник
источник
CREATE TABLE
код.Ответы:
Нет
ORDER BY
вSQL UPDATE
команде. Postgres обновляет строки в произвольном порядке:Чтобы избежать взаимных блокировок с абсолютной уверенностью, вы можете выполнять свои операторы в сериализуемой изоляции транзакций . Но это дороже, и вам нужно подготовиться к повторению команд при сбое сериализации.
Ваш лучший способ действий, вероятно, заключается в том, чтобы явно заблокировать его
SELECT ... ORDER BY ... FOR UPDATE
в подзапросе или в отдельнойSELECT
транзакции - по умолчанию на уровне изоляции «чтение зафиксировано». Цитирую Тома Лейна на pgsql-general :Это должно сделать работу:
Многостолбцовый индекс
(baz, bar)
может быть идеальным для производительности. Но такbar
как он, очевидно, обновлен очень сильно , индекс в одну колонку(baz)
может быть даже лучше. Зависит от пары факторов. Сколько строк вbaz
? Возможны ли горячие обновления без многоколоночного индекса? ...Если
baz
он обновляется одновременно, маловероятно, что в случае конфликта возникнет угроза (согласно документации) :Кроме того , если вы должны иметь уникальное ограничение с участием
bar
, рассмотримDEFERRABLE
ограничение , чтобы избежать уникальных нарушений в одной и той же команды. Связанный ответ:источник
id
или по какой-то другой уникальной колонкеbar
, не должно быть углового случая или падения производительности, верно?