Ist "CREATE INDEX" in MySQL eine lineare Operation?

20

Was ich meine ist folgendes:

Wenn das Erstellen eines Index für eine Tabelle mit nZeilen einige tZeit in Anspruch nimmt . Das Erstellen eines Index für dieselbe Tabelle 1000*ndauert ungefähr einige 1000*tZeit.

Ich versuche zu erreichen, indem ich die Zeit abschätze, die zum Erstellen des Index für die Produktionsdatenbank erforderlich ist, indem ich denselben Index für die viel kleinere Testdatenbank erstelle .

Nifle
quelle

Antworten:

16

Die Indexerstellung ist im Wesentlichen eine Sortieroperation, weist also bestenfalls eine n log ndurchschnittliche Wachstumskomplexität auf (Sie werden möglicherweise feststellen, dass sie in einigen Fällen besser abschneidet und wahrscheinlich nicht viel schlechter abschneidet).

Wenn alle relevanten Datenseiten in den Arbeitsspeicher passen und sich bereits im Arbeitsspeicher befinden, passt auch der Index und Ihr DBMS erzwingt nicht, dass Indexseiten geschrieben werden, bevor die Erstellung abgeschlossen ist (daher werden Indexblöcke nicht mehrmals auf der Festplatte aktualisiert) Die Geschwindigkeit, mit der der resultierende Index auf die Festplatte geschrieben wird, ist höher als die Zeit, die für die Sortierung benötigt wird. Sie nähern sich also möglicherweise einer linearen Beziehung zwischen der Anzahl der Zeilen und der Zeit, die für die Indexerstellung erforderlich ist. aber wenn Sie den schlimmsten Fall annehmen, sind Sie weniger wahrscheinlich unangenehm überrascht!

Denken Sie daran, dass, wenn Sie den Zugriff auf die Produktionsdatenbank während des Vorgangs nicht beenden, eine Indexerstellung um die IO-Bandbreite und / oder Sperren mit anderen Aktivitäten konkurriert. Versuchen Sie daher, dies zu berücksichtigen, wenn Sie Ihre Timing-Schätzungstests durchführen auf einem anderen System, auch wenn es identisch konfiguriert ist.

David Spillett
quelle
7

Erwähnenswert ist auch, dass Sie, wenn Sie die Spindeln für die Indizes von den Spindeln für die Tabelle trennen können, gleichzeitig von zwei Platten aus arbeiten können (beschränkt auf die Geschwindigkeit des Plattencontrollers in der Mitte, wenn ein RAID oder ähnliches, aber es wird immer noch schneller als eine Festplatte sein).

Mir ist klar, dass das Erstellen eines Indexes keine reine Lese- / Schreiboperation ist, sondern die Dinge erheblich beschleunigt.

CAVEATS: Ich bin selbst ein MSSQL-Typ, und daher bin ich mir bei MySQL nicht sicher, aber ich muss mir vorstellen, dass das Konzept des Aufteilens von Spindeln nicht spezifisch für SQLServer und Oracle ist (wo ich gehört habe, dass dort auch über IIRC gesprochen wird) ). Ich würde einfach nicht wissen, wie ich dieses Konzept aufstellen soll. In SQLServer-Begriffen würde es jedoch bedeuten, eine separate Dateigruppe neben sich zu haben PRIMARYund die Indizes auf die andere Dateigruppe zu legen, wobei die andere Dateigruppe einer Gruppe von Spindeln zugewiesen wird, die keine PRIMARYRolle spielt (die Vergabe von Spindelpositionen gegenüber Dateigruppen ist insgesamt eine andere Geschichte).

jcolebrand
quelle
1
So ziemlich dasselbe in Oracle - nur die Dateigruppen werden als Tablespace bezeichnet
Joe
1

Es hängt davon ab, ob.

Variable # 1: Wenn MySQL den oder die Index (e) im laufenden Betrieb erstellt oder wartet, bis alle Daten vorhanden sind, dann sortiert usw., um den Index zu erstellen. Hinweis: (Ich denke) EINZIGARTIGE Indizes müssen im laufenden Betrieb erstellt werden, damit die EINZIGARTIGKEIT überprüft werden kann. Der PRIMARY KEY für InnoDB wird mit den Daten gespeichert (oder Sie können es auch andersherum angeben), sodass MUSS zufällig erstellt werden.

Variable Nr. 2: Der Index verfolgt die Daten (z. B. AUTO_INCREMENT oder Zeitstempel) gegenüber zufällig (GUID, MD5) oder irgendwo dazwischen (Teilenummer, Name, friend_id).

Variable # 3 (wenn der Index direkt erstellt wird): Der Index passt möglicherweise in den Cache (key_buffer oder innodb_buffer_pool) oder wird auf die Festplatte übertragen.

Indizes, die die Daten verfolgen, sind unabhängig von der Antwort auf # 1 effizient und nahezu linear.

Zufällige IDs sind ein Schmerz. Wenn der Index nicht in den Cache passt, ist die Erstellungszeit ungeachtet der anderen Variablen viel schlechter als linear. (In diesem Fall bin ich mit Rolando nicht einverstanden.) Eine riesige InnoDB-Tabelle mit einer GUID für die PK ist schmerzhaft langsam, um sie einzufügen - planen Sie mit 100 Zeilen / Sek. Für normale Festplatten; vielleicht 1000, wenn Sie SSDs haben. LOAD DATA und Batched INSERTs bringen Sie nicht über die Langsamkeit des zufälligen Speichers hinaus.

3,53 bis 5,6 - nicht viel hat sich geändert.

Mehrfachspindeln? RAID-Striping ist in fast jeder Situation besser, als dies hier und das dort manuell zuzuweisen. Manuelle Aufteilung führt zu unausgeglichenen Situationen - ein Tabellenscan bleibt auf der Datenplatte hängen; Eine Nur-Index-Operation bleibt auf der Indexplatte hängen. eine einsame Abfrage trifft zuerst auf die Indexplatte, dann auf die Datenplatte (keine Überlappung); etc.

Rick James
quelle