it-swarm.com.de

Effizienteste Methode zum Erstellen eines Index in Postgres

Ist es effizienter, einen Index zu erstellen, nachdem das Laden der Daten abgeschlossen ist, oder spielt es keine Rolle?

Angenommen, ich muss 500 Dateien in eine Postgres 8.4-Datenbank laden. Hier sind die beiden Szenarien zur Indexerstellung, die ich verwenden könnte:

  1. Erstellen Sie einen Index, wenn eine Tabelle erstellt wird, und laden Sie dann jede Datei in die Tabelle. oder
  2. Erstellen Sie einen Index, nachdem alle Dateien in die Tabelle geladen wurden.

Die Tabellendaten selbst betragen ca. 45 Gigabyte. Der Index beträgt ungefähr 12 Gigabyte. Ich verwende einen Standardindex. Es ist so angelegt:

CREATE INDEX idx_name ON table_name (column_name);

Meine Daten werden mit COPY FROM geladen.

Sobald alle Dateien geladen sind, werden keine Aktualisierungen, Löschvorgänge oder zusätzlichen Ladevorgänge für die Tabelle ausgeführt (die Datenmenge eines Tages wird sich nicht ändern). Ich wollte also fragen, welches Szenario am effizientesten ist. Erste Tests scheinen darauf hinzudeuten, dass das Laden aller Dateien und das anschließende Erstellen des Index (Szenario 2) schneller ist, aber ich habe keinen wissenschaftlichen Vergleich der beiden Ansätze durchgeführt.

43
user1356386

Ihre Beobachtung ist richtig - es ist viel effizienter, zuerst Daten zu laden und dann erst einen Index zu erstellen. Grund dafür ist, dass Indexaktualisierungen beim Einfügen teuer sind. Wenn Sie einen Index erstellen, nachdem alle Daten vorhanden sind, ist dies viel schneller.

Es geht sogar noch weiter: Wenn Sie große Datenmengen in eine vorhandene indizierte Tabelle importieren müssen, ist es häufig effizienter, zuerst den vorhandenen Index zu löschen, die Daten zu importieren und dann den Index erneut zu erstellen.

Ein Nachteil der Indexerstellung nach dem Import ist, dass die Tabelle gesperrt werden muss und dies möglicherweise lange dauert (im umgekehrten Szenario wird sie nicht gesperrt). In PostgreSQL 8.2 und höher können Sie jedoch CREATE INDEX CONCURRENTLY verwenden, wodurch die Tabelle während der Indizierung nicht gesperrt wird (mit einigen Einschränkungen).

72
mvp