Eine steile These aus dem Datenbankalltag sorgt für Diskussion: Das einzige wirklich skalierbare DELETE in Postgres sei DROP TABLE. Dahinter steckt eine genaue Beobachtung, wie Postgres mit gelöschten Zeilen umgeht.

drweb.de als bevorzugte Quelle auf Google hinzufügenQualitätsgeprüfte Inhalte direkt in Google News & DiscoverJetzt hinzufügen

Ein großes DELETE in Postgres gibt keinen Speicher frei, sondern legt zusätzliche Arbeit auf die Datenbank. Der PlanetScale-Ingenieur Tom Pang erklärt, warum das so ist und welche Wege besser skalieren.

Das Wichtigste in Kürze

  • Große DELETEs erzeugen in Postgres tote Zeilenversionen und zusätzliche Vacuum- und Replikationslast.
  • DROP TABLE und TRUNCATE skalieren dagegen weitgehend unabhängig von der Datenmenge.
  • Partitionierung verwandelt laufendes Löschen in ein gelegentliches DROP der ältesten Partition.

Warum kostet Löschen mehr, als es bringt?

Aktenschrank-Schublade mit grünen Hängemappen, viermal mit
Postgres speichert gelöschte Zeilen zunächst weiter. DELETE markiert sie nur als tot, erst Vacuum gibt Speicher frei. Replikation erhöht die Schreiblast

Postgres hält dank seines Mehrversionen-Verfahrens (MVCC) alte und gelöschte Zeilen zunächst neben den aktuellen. Ein DELETE markiert sie nur als tot und fügt damit Arbeit hinzu, statt sie zu erledigen. Erst ein späterer Vacuum-Lauf gibt die Bytes zur Wiederverwendung frei.

Hinzu kommt die Replikationslast. Jedes Löschen ist technisch ein Schreibvorgang, der zu den Replikaten wandert und andere Schreiber ausbremsen kann. Den freigewordenen Platz bekommt das Betriebssystem dabei in der Regel gar nicht zurück.

Was skaliert stattdessen?

Miniaturarbeiter fegt Krümel, Modellkran mit Text „POSTGRES DROP“ steht daneben
DROP TABLE und TRUNCATE löschen Tabellen sofort ohne tote Zeilen, benötigen aber kurzzeitig harte Sperren. Partitionierung hilft beim laufenden Aufräumen historischer Daten

DROP TABLE und TRUNCATE entfernen die Dateien direkt und arbeiten unabhängig von der Datenmenge. Sie hinterlassen keine toten Zeilen und keine Vacuum-Schuld, verlangen aber für kurze Zeit eine harte Sperre auf der Tabelle.

Für laufendes Aufräumen hilft Partitionierung. Beim Ablegen historischer Daten nach Datum in Kindtabellen lassen sich alte Zeiträume später per DROP der ganzen Partition entfernen. Aus vielen teuren DELETEs wird so ein billiges, planbares Entfernen.

Datenbanken bestraft niemand für sauberes Aufräumen, wohl aber für das falsche Werkzeug. Ein Schema, das von Anfang an auf DROP statt DELETE setzt, spart später viel Vacuum-Ärger.

— Markus Seyfferth, Chefredakteur Dr. Web

Wie räumt man einmalig sauber auf?

Toilette mit einem orangefarbenen „DROP“-Knopf auf dem Sitz und einer kleinen, dunklen Fernbedienung im Wasser
Großputz in Datenbanken: Gute Zeilen in Temp-Tabelle, Original truncaten, Zeilen zurück. Nur Minuten statt langer Sperre

Für einen einmaligen Großputz empfiehlt Pang einen Umweg über eine Temp-Tabelle. Die zu behaltenden Zeilen wandern in eine temporäre Tabelle, danach folgt ein TRUNCATE der Originaltabelle, anschließend kommen die guten Zeilen zurück. In seinem Beispiel dauerte das nur wenige Minuten.

Steht eine lange Sperre nicht zur Wahl, bleibt das Löschen in kleinen Stapeln, etwa zehntausend Zeilen pro Durchgang. Das hält die Transaktionen kurz und lässt den Autovacuum mithalten. Die Wahl der Datenbank-Umgebung hängt auch am Hosting, Optionen vergleicht unser WordPress Hosting Vergleich. Die ausführliche Begründung samt SQL liefert der PlanetScale-Blog.

Mehr Newshunger?

4,4 16 Bewertungen

Wie hat Ihnen dieser Artikel gefallen?