Büyük bir tabloya seri sütun eklemenin en etkili yolu


10

Büyük bir tabloya BIGSERIAL sütunu eklemenin en hızlı yolu nedir (~ 3 Bil. Satır, ~ 174Gb)?

DÜZENLE:

  • Sütun mevcut satırlar ( NOT NULL) için değerleri artırılmasını istiyorum .
  • (Geriye dönüp baktığımda kötü bir karara benzeyen) bir dolgu oluşturmadım.
  • Disk alanıyla ilgili bir sorunum yok, sadece olabildiğince hızlı olmasını istiyorum.

Yanıtlar:


12

Sorun ne:

ALTER TABLE foo ADD column bar bigserial;

Otomatik olarak benzersiz değerlerle doldurulacaktır (1 ile başlayan).

Varolan her satır için bir sayı istiyorsanız , tablodaki her satırın güncellenmesi gerekir . Yoksa değil mi?

Veri sayfalarında ölü tuplleri veya boş alanı yeniden kullanamazsa, tablo boyutunun iki katı kadar şişirilir. Operasyonun performansı FILLFACTOR, masaya yayılmış 100'den daha düşük veya sadece rastgele ölü kaplardan çok yararlanabilir . Başka VACUUM FULL ANALYZEdisk alanı kurtarmak için daha sonra çalıştırmak isteyebilirsiniz . Ancak bu hızlı olmayacak.

pgstattuple
Bu uzantıyla ilgileniyor olabilirsiniz. Tablolarınızda istatistik toplamanıza yardımcı olur. Ölü kaplumbağalar ve boş alan hakkında bilgi edinmek için:

Databae başına uzantıyı bir kez yükleyin:

CREATE EXTENSION pgstattuple;

Aramak:

SELECT * FROM pgstattuple('tbl');

Alternatif

Eğer görünümler, yabancı anahtarlar, bağlı kırmak olacak yeni bir tablo oluşturmak için göze eğer ...

Eski tablonun boş bir kopyasını oluşturun:

CREATE new_tbl AS
SELECT *
FROM   old_tbl
LIMIT  0;

Bigserial sütununu ekleyin:

ALTER new_tbl ADD column bar bigserial;

Büyük tabloyu otomatik olarak doldurarak eski tablodan veri ekle:

INSERT INTO new_tbl
SELECT *    --  new column will be filled with default
FROM   old_tbl
ORDER  BY something; -- or don't order if you don't care: faster

INSERT SELECT öğesinde yeni bigserial sütunu eksik ve otomatik olarak varsayılan değeriyle doldurulur . Tüm sütunları heceleyebilir nextval()ve SELECTlisteye aynı efekti ekleyebilirsiniz .

Tüm verilerinizi yeni tabloya aldığınızdan emin olun. Şimdi
eski tablodaki dizinleri, kısıtlamaları, tetikleyicileri ekleyin .

DROP TABLE old_tbl;
ALTER TABLE new_tbl RENAME TO old_tbl;

Genel olarak biraz daha hızlı olabilir. Bu size herhangi bir şişkinlik olmadan vanilya masası (ve indeksler) bırakır.

Boşluk alanı olarak - tablonun durumuna bağlı olarak - eski tablonun büyüklüğü civarında boş disk alanına ihtiyacınız var. Ancak, masa şişmesi nedeniyle ilk basit yöntemle ihtiyacınız olabilir. Yine, ayrıntılar tablonuzun durumuna bağlıdır.


3
Alternatifi çok daha hızlı olacak tek bir işlemle sarın. Ek fsyncs'den kaçınacak
Frank Heikens
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.