it-swarm.com.de

Die effizienteste Möglichkeit, einer großen Tabelle eine serielle Spalte hinzuzufügen

Was ist der schnellste Weg, um einer riesigen Tabelle eine BIGSERIAL-Spalte hinzuzufügen (~ 3 Bil. Zeilen, ~ 174 GB)?

BEARBEITEN:

  • Ich möchte, dass die Spalte inkrementierte Werte für vorhandene Zeilen enthält (NOT NULL).
  • Ich habe keinen Füllfaktor eingestellt (was im Nachhinein nach einer schlechten Entscheidung aussieht).
  • Ich habe kein Problem mit dem Speicherplatz, möchte nur, dass er so schnell wie möglich ist.
10

Was ist falsch mit:

ALTER TABLE foo ADD column bar bigserial;

Wird automatisch mit eindeutigen Werten gefüllt (beginnend mit 1).

Wenn Sie eine Nummer für jede vorhandene Zeile wünschen, muss jede Zeile in der Tabelle aktualisiert werden . Oder nicht?

Die Tabelle wird auf die doppelte Größe aufgebläht, wenn tote Tupel oder freier Speicherplatz auf den Datenseiten nicht wiederverwendet werden können. Die Leistung der Operation kann stark von einem FILLFACTOR unter 100 oder nur zufälligen toten Tupeln profitieren, die über die Tabelle verteilt sind. Andernfalls möchten Sie möglicherweise VACUUM FULL ANALYZE Danach ausführen, um Speicherplatz wiederherzustellen. Dies wird jedoch nicht schnell gehen.

pgstattuple
Diese Erweiterung könnte Sie interessieren. Es hilft Ihnen, Statistiken über Ihre Tabellen zu sammeln. Um mehr über tote Tupel und freien Speicherplatz zu erfahren:

Installieren Sie die Erweiterung einmal pro Datenbank:

CREATE EXTENSION pgstattuple;

Anruf:

SELECT * FROM pgstattuple('tbl');

Alternative

Wenn Sie es sich leisten können, eine neue Tabelle zu erstellen, die abhängig von Ansichten, Fremdschlüsseln, ...

Erstellen Sie eine leere Kopie der alten Tabelle:

CREATE new_tbl AS
SELECT *
FROM   old_tbl
LIMIT  0;

Fügen Sie die Bigserial-Spalte hinzu:

ALTER new_tbl ADD column bar bigserial;

INSERT-Daten aus alter Tabelle, die das Bigserial automatisch ausfüllen:

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

Die neue Bigserial-Spalte fehlt in SELECT des INSERT und lautet wird automatisch mit dem Standardwert gefüllt . Sie können alle Spalten buchstabieren und nextval() zur Liste SELECT hinzufügen, um denselben Effekt zu erzielen.

Stellen Sie sicher, dass Sie alle Ihre Daten in der neuen Tabelle haben.
Fügen Sie Indizes, Einschränkungen und Trigger hinzu, die Sie in der alten Tabelle hatten jetzt.

DROP TABLE old_tbl;
ALTER TABLE new_tbl RENAME TO old_tbl;

Könnte insgesamt etwas schneller sein. Dadurch erhalten Sie eine Vanille-Tabelle (und Indizes) ohne Aufblähen.

Sie benötigen freien Speicherplatz - ungefähr so ​​groß wie die alte Tabelle, abhängig vom Status der Tabelle - als Spielraum. Bei der ersten einfachen Methode benötigen Sie möglicherweise genau so viel, weil der Tisch aufgebläht ist. Auch hier hängen die Details vom Status Ihrer Tabelle ab.

12