2013-09-02 9 views
27

Ist es effizienter, einen Index zu erstellen, nachdem das Laden von Daten abgeschlossen ist oder vorher, oder spielt es keine Rolle?Der effizienteste Weg, um einen Index in Postgres zu erstellen

Zum Beispiel sagen, ich habe 500 Dateien in eine Postgres 8.4 DB zu laden. Hier sind die zwei Indexerstellungsszenarien, die ich verwenden könnte:

  1. Index erstellen, wenn Tabelle erstellt wird, laden Sie dann jede Datei in Tabelle; oder
  2. Index erstellen, nachdem alle Dateien in die Tabelle geladen wurden.

die Tabellendaten selbst ist etwa 45 Gigabyte. Der Index beträgt etwa 12 Gigabyte. Ich verwende einen Standardindex. Es wird wie folgt erstellt:

CREATE INDEX idx_name ON table_name (column_name); 

Mein Laden von Daten verwendet COPY FROM.

Sobald alle Dateien geladen werden, keine Aktualisierungen, Löschungen oder zusätzliche Lasten auf den Tisch kommen (es ist ein Wert von Daten des Tages, die sich nicht ändern). Also wollte ich fragen, welches Szenario am effizientesten wäre? Erste Tests scheinen darauf hinzuweisen, dass das Laden aller Dateien und das anschließende Erstellen des Indexes (Szenario 2) schneller ist, aber ich habe keinen wissenschaftlichen Vergleich der beiden Ansätze durchgeführt.

Antwort

43

Ihre Beobachtung ist richtig - es ist viel effizienter, Daten zuerst zu laden und erst dann den Index zu erstellen. Der Grund dafür ist, dass Indexaktualisierungen während der Einfügung 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 bestehende indizierte Tabelle importieren müssen, ist es oft effizienter, den vorhandenen Index zuerst zu löschen, die Daten zu importieren und dann den Index erneut zu erstellen.

Ein Nachteil des Index erstellt nach dem Import ist, dass Tabelle gesperrt werden muß, und dass lange Zeit in Anspruch nehmen (es wird nicht in entgegengesetztem Szenario gesperrt werden). In PostgreSQL 8.2 und höher können Sie jedoch CREATE INDEX CONCURRENTLY verwenden, wodurch die Tabelle während der Indexierung nicht gesperrt wird (mit einigen Einschränkungen).

+0

Nun, wenn Tabelle gesperrt ist kann niemand lesen oder schreiben, was sehr nervig sein kann, auch nachts. Sie sind besser dran mit CREATE INDEX CONCURRENTly – mvp

+0

@BradTilley: Ich dachte, es war neue Funktion, aber PostgreSQL 8.4 [unterstützt es] (http://www.postgresql.org/docs/8.4/static/sql-createindex.html). – mvp

+4

"* wenn die Tabelle gesperrt ist, kann niemand lesen oder schreiben *" - Ich denke nicht, dass das stimmt. Wenn ein 'CREATE INDEX 'ausgeführt wird, kann die Tabelle zwar gelesen, aber nicht aktualisiert werden, wenn ich mich nicht irre. –

Verwandte Themen