Postgres'te eşzamanlı güncellemeleri optimize etme


9

Ben böyle eşzamanlı Postgres sorguları çalıştırıyorum:

UPDATE foo SET bar = bar + 1 WHERE baz = 1234

Her sorgu satırların sabit K sayısını etkiler ve ben satırların güncellenme sırasını zorlamak için bir yol bulamıyorum, ben deadlock ile sonuçlanır. Şu anda siparişi elle uygulayarak sorunu düzeltiyorum, ancak bu, arama karmaşıklığını O (log N + K) 'den O (K log N)' ye yükseltirken normalde yaptığımdan çok daha fazla sorgu yürütmem gerektiği anlamına geliyor.

Kilitlenmelere karşı savunmasız kalmadan performansı artırmanın bir yolu var mı? Postgres'in satırları taradığı sırayla güncellemesi şartıyla dizini (baz)dizinle değiştirmenin (baz, id)işe yarayabileceğinden şüpheleniyorum , bu izlemeye değer bir yaklaşım mı?


CREATE TABLEKodu eklemenizi öneririm .
ypercubeᵀᴹ

Yanıtlar:


15

Hiçbir yoktur ORDER BYbir in SQL UPDATEkomutası. Postgres satırları keyfi sırada günceller:

Mutlak kesinliğe sahip kilitlenmeleri önlemek için, ifadelerinizi serileştirilebilir işlem yalıtımında çalıştırabilirsiniz . Ancak bu daha pahalıdır ve serileştirme arızasında komutları tekrarlamaya hazırlanmanız gerekir.

En iyi eylem yönteminiz muhtemelen SELECT ... ORDER BY ... FOR UPDATEbir alt sorguda veya SELECTbir işlemde bağımsız olarak açıkça kilitlenmektir - varsayılan olarak "tamamlandı" yalıtım düzeyi. Tom Lane'den pgsql-general'den alıntı :

İyi olmalı --- FOR UPDATE kilitleme her zaman SELECT boru hattındaki son adımdır.

Bu işi yapmalıdır:

BEGIN;

SELECT 1
FROM   foo 
WHERE  baz = 1234
ORDER  BY bar
FOR    UPDATE;

UPDATE foo
SET    bar = bar + 1
WHERE  baz = 1234;

COMMIT;

Üzerinde çok sütunlu bir dizin (baz, bar)performans için mükemmel olabilir. Ancak barçok açık bir şekilde güncellendiğinden , tek sütunlu bir dizin (baz)daha da iyi olabilir. Birkaç faktöre bağlıdır. Kaç satır baz? Are SICAK güncellemeler çok sütun indeksi olmadan mümkün? ...

Eğer baz aynı anda güncellenir, beklenmedik bir hala var köşe vaka çakışmaları şans (belgelerine başına) :

İşlem yalıtım düzeyinde SELECTçalışan ve satırları sıra dışı döndürmek için bir kilitleme yan tümcesi READ COMMITTEDkullanan bir komut mümkündür ORDER BY. ...

Eğer kapsayan benzersiz kısıtlama olmalıdır Ayrıca, bar, bir düşünün DEFERRABLEkısıtlamayı aynı komuta kademelerinde benzersiz ihlallerini önlemek için. İlgili cevap:


1
Sipariş idyerine veya başka bir benzersiz sütun sipariş edersem bar, bir köşe durumu veya bir performans isabeti olmamalıdır, değil mi?
Alexei Averchenko

@AlexeiAverchenko: Evet, asla güncellenmeyen benzersiz bir sütun bunun için mükemmel olurdu - ve bu sütunu ikinci pozisyona dahil eden çok sütunlu bir dizin.
Erwin Brandstetter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.