12

So habe ich eine Tabelle mit einem großen Dataset und diese Tabelle hat drei Spalten, die ich fallen lassen möchte.
Die Frage ist: Wie wird Postgres damit umgehen?Löschen Spalte in Postgres auf einem großen Dataset

Wird es durch jeden Eintrag gehen oder wird es einfach Mapping-Informationen ohne viel Overhead aktualisieren? Kann ich einfach eine ALTER TABLE machen oder soll ich in diesem speziellen Fall eine Swap-Tabelle verwenden?

Und wenn es einen Unterschied macht, haben alle drei Spalten eine feste Länge (zwei ganze Zahlen und eine numerische).

Es tut mir leid, wenn es bereits gefragt worden ist, aber Google konnte keine Fragen/artikel ...

Antwort

20

ALTER TABLE DROP COLUMN nicht nur gerade Spalten in Systemtabellen zu deaktivieren. Es ist sehr schnell, aber es entfernt keine Daten von Heap-Dateien. Sie müssen VACUUM FULL später ausführen, um den zugewiesenen Dateibereich zu komprimieren. ALTER TABLE DROP COLUMN ist also sehr schnell. Und du würdest Dateien komprimieren, du musst langsamer (mit exklusivem LOCK) VACUUM FULL aufrufen.

16

Google für diese Frage nutzlos sein, aber the manual rarely fails:

Die DROP COLUMN Form entfernt nicht physisch die Spalte, aber einfach macht es auf SQL-Operationen unsichtbar. Nachfolgende Einfügeoperationen und Aktualisierungsoperationen in der Tabelle speichern einen Nullwert für die Spalte. Das Löschen einer Spalte ist also schnell, aber die Größe der Tabelle auf der Festplatte wird nicht sofort um reduziert, da der von der Spalte belegte Speicherplatz nicht zurückgewonnen wird. Der Speicherplatz wird im Laufe der Zeit zurückgewonnen, da vorhandene Zeilen aktualisiert werden.

Und:

Um eine sofortige Umschreiben der Tabelle zu erzwingen, können Sie VACUUM FULL, CLUSTER oder eine der Formen von ALTER TABLE verwenden, die eine Rewrite zwingt. Diese führt zu keiner semantisch sichtbaren Änderung in der Tabelle, sondern löscht von nicht mehr nützlichen Daten.

Insbesondere wird die Spalte attisdropped im Systemkatalog Tabelle pg_attribute zu TRUE gesetzt.

+2

Interessanterweise, weil Zeilenaktualisierungen jetzt NULL in den abgelegten Spalten "speichern". Und da postgresql Nullen speichert, indem ein Bit in der optionalen "Null-Bitmap" gesetzt wird, muss _every_ row jetzt eine Null-Bitmap (mit einer Größe von einem Byte für jede acht gelöschte oder nicht gelöschte Spalte) haben, selbst wenn keine der sichtbaren Zeilen vorhanden sind NULL –