Yeni bir tablo oluşturmak yerine, aynı tabloyu kestikten sonra aynı tabloya benzersiz satırlar da ekleyebilirsiniz. Hepsini tek bir işlemde yapın .
Bu yaklaşım, yalnızca tablonun her yerinden silinecek çok sayıda satır olduğunda kullanışlıdır. Sadece birkaç kopya için düz kullanın DELETE
.
Milyonlarca satırdan bahsettiniz. İşlemi hızlandırmak için, oturum için yeterli geçici arabellek ayırmak istiyorsunuz . Geçerli oturumunuzda herhangi bir geçici tampon kullanılmadan önce ayarın yapılması gerekir . Masanızın boyutunu bulun:
SELECT pg_size_pretty(pg_relation_size('tbl'));
temp_buffers
En azından biraz daha üstüne ayarlayın .
SET temp_buffers = 200MB;
BEGIN;
CREATE TEMP TABLE t_tmp AS
SELECT DISTINCT * FROM tbl
ORDER BY id;
TRUNCATE tbl;
INSERT INTO tbl
SELECT * FROM t_tmp;
COMMIT;
Bu yöntem, bağlı nesneler varsa , yeni bir tablo oluşturmaya göre daha üstün olabilir . Tabloya referans veren görünümler, dizinler, yabancı anahtarlar veya diğer nesneler. TRUNCATE
yine de temiz bir sayfayla başlamanızı sağlar (arka planda yeni dosya) ve büyük tablolardan çok daha hızlıdır DELETE FROM tbl
( DELETE
aslında küçük tablolarda daha hızlı olabilir).
Büyük masalar için düzenli olarak daha hızlıdır dizinleri ve yabancı anahtarları (FK) bırakmak, tabloyu yeniden doldurmak ve bu nesneleri yeniden oluşturmak . FK kısıtlamaları söz konusu olduğunda, yeni verilerin geçerli olduğundan emin olmalısınız, yoksa FK'yi oluşturmaya çalışırken istisnalarla karşılaşırsınız.
Bundan TRUNCATE
daha agresif kilitleme gerektirdiğini unutmayın DELETE
. Bu, ağır, eşzamanlı yüke sahip tablolar için bir sorun olabilir. Ancak yine de masayı tamamen bırakıp değiştirmekten daha az rahatsız edici.
Bir TRUNCATE
seçenek değilse veya genellikle küçük ila orta büyüklükteki tablolar için , veri modifiye edici CTE ile benzer bir teknik vardır (Postgres 9.1 +):
WITH del AS (DELETE FROM tbl RETURNING *)
INSERT INTO tbl
SELECT DISTINCT * FROM del;
ORDER BY id;
Büyük masalar için daha yavaş çünkü TRUNCATE
için daha orada daha hızlı. Ancak küçük masalar için daha hızlı (ve daha basit!) Olabilir.
Bağlı nesneleriniz yoksa, yeni bir masa oluşturabilir ve eskisini silebilirsiniz, ancak bu evrensel yaklaşımdan neredeyse hiçbir şey elde edemezsiniz.
Mevcut RAM'e sığmayan çok büyük tablolar için yeni bir tablo daha hızlı olacaktır. Bunu, bağlı nesnelerle olası sorunlara / ek yüklere karşı tartmanız gerekecek.