Ist es besser, einen Index zu erstellen, bevor eine Tabelle mit Daten gefüllt wird oder nachdem die Daten vorhanden sind?

86

Ich habe eine Tabelle mit ungefähr 100 Millionen Zeilen, die ich kopieren werde, um sie zu ändern und einen Index hinzuzufügen. Ich bin nicht so besorgt über die Zeit, die zum Erstellen der neuen Tabelle benötigt wird. Wird der erstellte Index jedoch effizienter, wenn ich die Tabelle vor dem Einfügen von Daten ändere oder die Daten zuerst einfüge und dann den Index hinzufüge?

Drew Stephens
quelle

Antworten:

110

Das Erstellen eines Index nach dem Einfügen von Daten ist effizienter (es wird sogar häufig empfohlen, den Index vor dem Stapelimport zu löschen und nach dem Import neu zu erstellen).

Synthetisches Beispiel (PostgreSQL 9.1, langsame Entwicklungsmaschine, eine Million Zeilen):

CREATE TABLE test1(id serial, x integer);
INSERT INTO test1(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 7816.561 ms
CREATE INDEX test1_x ON test1 (x);
-- Time: 4183.614 ms

Index einfügen und dann erstellen - ca. 12 Sek

CREATE TABLE test2(id serial, x integer);
CREATE INDEX test2_x ON test2 (x);
-- Time: 2.315 ms
INSERT INTO test2(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 25399.460 ms

Index erstellen und dann einfügen - ca. 25,5 Sekunden (mehr als zweimal langsamer)

Valodzka
quelle
5
+1, Indizes verlangsamen einen Vorgang mit 100 Millionen Zeilen einfügen deutlich, daher ist es besser, sie zu löschen und neu zu erstellen.
Code4life
10

Es ist wahrscheinlich besser, den Index nach dem Hinzufügen der Zeilen zu erstellen. Es wird nicht nur schneller sein, sondern der Baumausgleich wird wahrscheinlich besser sein.

Das Bearbeiten von "Balancing" ist hier wahrscheinlich nicht die beste Auswahl an Begriffen. Im Fall eines B-Baums ist er per Definition ausgeglichen. Dies bedeutet jedoch nicht, dass der B-Baum das optimale Layout hat. Die Verteilung der untergeordneten Knoten innerhalb der Eltern kann ungleichmäßig sein (was zu höheren Kosten bei zukünftigen Aktualisierungen führt), und die Baumtiefe kann tiefer als erforderlich sein, wenn der Ausgleich während der Aktualisierungen nicht sorgfältig durchgeführt wird. Wenn der Index nach dem Hinzufügen der Zeilen erstellt wird, ist die Verteilung wahrscheinlicher. Darüber hinaus sind Indexseiten auf der Festplatte nach dem Erstellen des Index möglicherweise weniger fragmentiert. Ein bisschen mehr Informationen hier

Mark Wilkins
quelle
2

Dies spielt bei diesem Problem keine Rolle, weil:

  1. Wenn Sie zuerst Daten zur Tabelle hinzufügen und danach einen Index hinzufügen. Ihre Indexerstellungszeit ist O(n*log(N))länger (wobei nZeilen hinzugefügt werden). Da die Baumgerating-Zeit O(N*log(N))dann ist, wenn Sie diese in alte und neue Daten aufteilen, können Sie O((X+n)*log(N))diese einfach in konvertieren O(X*log(N) + n*log(N))und in diesem Format können Sie einfach sehen, worauf Sie zusätzlich warten werden.
  2. Wenn Sie einen Index hinzufügen und danach Daten einfügen. In jeder Zeile (Sie haben nneue Zeilen) erhalten Sie mehr Zeit O(log(N))zum Einfügen der zusätzlichen Struktur, die zum Wiederherstellen der Struktur des Baums nach dem Hinzufügen eines neuen Elements erforderlich ist (Indexspalte aus neuer Zeile, da der Index bereits vorhanden ist und eine neue Zeile hinzugefügt wurde, muss der Index auf ausgeglichen neu generiert werden Struktur, diese Kosten, O(log(P))wo Pist eine Indexleistung [Elemente im Index] ). Sie haben nneue Zeilen dann schließlich haben Sie n * O(log(N))dann O(n*log(N))Zusammenfassung zusätzliche Zeit.
Svisstack
quelle
1

Nachher erstellte Indizes sind in den meisten Fällen viel schneller. Ein typisches Beispiel: 20 Millionen Zeilen mit Volltext auf varchar (255) - (Business Name) Index beim Importieren von Zeilen - eine Übereinstimmung, die im schlimmsten Fall bis zu 20 Sekunden dauert. Index löschen und neu erstellen - jedes Mal weniger als 1 Sekunde dauern

Mike Cross
quelle
-2

Ich bin mir nicht sicher, ob es aus Gründen der Indexeffizienz wirklich wichtig ist, da Sie in beiden Fällen neue Daten in den Index einfügen. Der Server würde im Grunde genommen erst nach seiner Erstellung wissen, wie unausgeglichen ein Index sein würde. In Bezug auf die Geschwindigkeit werden die Einfügungen natürlich ohne Index ausgeführt.

GroßmeisterB
quelle