Korzystam z równoczesnych zapytań Postgres:
UPDATE foo SET bar = bar + 1 WHERE baz = 1234
Każde zapytanie wpływa na ustaloną liczbę K wierszy i nie mogę znaleźć sposobu na wymuszenie kolejności, w jakiej wiersze są aktualizowane, co powoduje zakleszczenie. Obecnie rozwiązuję ten problem ręcznie, wymuszając wykonanie zamówienia, ale oznacza to, że muszę wykonać o wiele więcej zapytań niż normalnie, jednocześnie zwiększając złożoność wyszukiwania z O (log N + K) do O (K log N).
Czy istnieje sposób na poprawę wydajności bez narażania się na impas? Podejrzewam, że zastąpienie (baz)
indeksu (baz, id)
indeksem może działać, pod warunkiem że Postgres aktualizuje wiersze w tej samej kolejności, w jakiej je przeskanował, czy jest to podejście warte zastosowania?
postgresql
locking
deadlock
update
Aleksiej Averchenko
źródło
źródło
CREATE TABLE
kodu.Odpowiedzi:
Nie ma
ORDER BY
wSQL UPDATE
poleceniu. Postgres aktualizuje wiersze w dowolnej kolejności:Aby uniknąć zakleszczeń z absolutną pewnością, możesz uruchamiać swoje wyciągi w formie szeregowalnej izolacji transakcji . Ale to jest droższe i musisz przygotować się do powtarzania poleceń w przypadku niepowodzenia serializacji.
Najlepszym sposobem jest prawdopodobnie jawne zablokowanie
SELECT ... ORDER BY ... FOR UPDATE
w podzapytaniu lub samodzielnymSELECT
w transakcji - w domyślnym poziomie izolacji „zatwierdzono odczyt”. Cytując Tom Lane w pgsql-general :To powinno wykonać zadanie:
Wielokolumnowy indeks
(baz, bar)
może być idealny do wydajności. Ale ponieważbar
jest oczywiście bardzo często aktualizowany , indeks jednokolumnowy(baz)
może być nawet lepszy. Zależy od kilku czynników. Ile wierszy nabaz
? Czy możliwe są aktualizacje HOT bez indeksu wielokolumnowego? ...Jeśli
baz
jest aktualizowana jednocześnie, wciąż jest mało prawdopodobne rogu przypadek szansa dla konfliktów (na dokumentacji) :Ponadto, jeśli powinieneś mieć wyjątkowe ograniczenie
bar
, rozważDEFERRABLE
ograniczenie, aby uniknąć unikalnych naruszeń w ramach tego samego polecenia. Powiązana odpowiedź:źródło
id
lub inną unikalną kolumnę zamiastbar
, nie powinno być narożnika ani hitu wydajności, prawda?