it-swarm.com.de

MySQL - Wie lange dauert es, einen Index zu erstellen?

Kann mir jemand sagen, wie man eine Schlüsselskala in MySQL hinzufügt? Ich habe 500.000.000 Zeilen in einer Datenbank, trans, mit Spalten i (INT UNSIGNED), j (INT UNSIGNED), nu (DOUBLE), A (DOUBLE). Ich versuche, eine Spalte zu indizieren, z.

ALTER TABLE trans ADD KEY idx_A (A);

und ich warte. Bei einer Tabelle mit 14.000.000 Zeilen dauerte die Ausführung auf meinem MacBook Pro ungefähr 2 Minuten, aber für die gesamte halbe Milliarde dauert es 15 Stunden und es wird gezählt. Mache ich etwas falsch oder bin ich nur naiv darüber, wie die Indizierung einer Datenbank mit der Anzahl der Zeilen skaliert?

34
xnx

Es gibt einige Faktoren, die zu berücksichtigen sind:

  • Die Sortierung ist eine N.log (N) -Operation.
  • Die Sortierung nach 14 Millionen Zeilen passt möglicherweise in den Hauptspeicher. Die Sortierung mit 500M-Zeilen ist wahrscheinlich nicht der Fall, so dass die Sortierung auf die Festplatte überläuft, was die Abläufe enorm verlangsamt.

Da der Faktor etwa 30 beträgt, wäre die nominale Sortierzeit für den großen Datensatz in der Größenordnung von 50 Mal so lang - unter zwei Stunden. Sie benötigen jedoch 8 Byte pro Datenwert und weitere 8 Byte Overhead (das ist eine Vermutung für mySQL, wenn Sie mehr darüber wissen, was in einem Index gespeichert wird). 14M × 16 ≈ 220 MB Hauptspeicher. Aber 500M × 16 × 8 GB Hauptspeicher. Wenn Ihr Computer nicht über so viel Speicher verfügt (und MySQL für die Verwendung konfiguriert ist), wird die große Sorte auf die Festplatte übertragen und dies macht den Rest der Zeit aus.

32

Erstens könnte Ihre Tabellendefinition hier einen großen Unterschied machen. Wenn Sie in Ihren Spalten keine NULL-Werte benötigen, definieren Sie sie NOT NULL. Dies spart Platz im Index und vermutlich Zeit beim Erstellen.

CREATE TABLE x ( 
  i INTEGER UNSIGNED NOT NULL, 
  j INTEGER UNSIGNED NOT NULL, 
  nu DOUBLE NOT NULL, 
  A DOUBLE NOT NULL 
);

Die Zeit, die zum Erstellen der Indizes benötigt wird, erfordert einen Tabellenscan und wird als REPAIR BY SORTING angezeigt. In Ihrem Fall sollte es schneller sein (d. H. Umfangreicher Datensatz), eine neue Tabelle mit den erforderlichen Indizes zu erstellen und die Daten darin einzufügen, da dies die REPAIR BY SORTING-Operation vermeidet, da die Indizes sequentiell auf der Einfügung erstellt werden. Ein ähnliches Konzept wird in diesem Artikel erläutert.

CREATE DATABASE trans_clone;
CREATE TABLE trans_clone.trans LIKE originalDB.trans;
ALTER TABLE trans_clone.trans ADD KEY idx_A (A);

Dann schreiben Sie die Einfügung in Abschnitte (wie in dem Artikel beschrieben) oder geben Sie die Daten mit MYSQLDUMP aus:

mysqldump originalDB trans  --extended-insert --skip-add-drop-table --no-create-db --no-create-info > originalDB .trans.sql
mysql trans_clone < originalDB .trans.sql

Dadurch werden die Daten eingefügt, es ist jedoch keine Neuerstellung des Index erforderlich (der Index wird beim Einfügen jeder Zeile erstellt) und sollte wesentlich schneller abgeschlossen werden. 

5
Andy

Aus meiner Erfahrung: Wenn die Hardware damit zurechtkommt, skaliert die Indizierung großer Tabellen mit MySQL normalerweise linear. Ich habe es bisher mit Tabellen mit etwa 100.000.000 Zeilen versucht, aber nicht auf einem Notebook - hauptsächlich auf starken Servern.

Ich denke, es hängt hauptsächlich von den Hardwarefaktoren ab, von der Art der von Ihnen verwendeten Tabellen-Engine (MyIsam, INNO oder was auch immer) und ein bisschen, wenn die Tabelle anderweitig verwendet wird. Im Allgemeinen sprang die Festplattennutzung im Gegensatz zur CPU-Nutzung in der Luft. Ich bin nicht sicher über die Festplatten des MacBook, aber ich denke, dass sie nicht die schnellsten sind.

Wenn Sie über MyISAM-Tabellen verfügen, schauen Sie sich die Indexdateien im Tabellenverzeichnis genauer an und sehen Sie, wie sich diese im Laufe der Zeit ändern.

2
Bjoern

Wenn der Sortierschritt eine N.log (N) -Operation ist, spart die Partitionierung Ihrer großen Tabelle theoretisch Zeit 

Etwa 30% Gewinn für eine Tabelle mit 500 000 000 Zeilen, die in 100 gleich großen Dateien unterteilt sind: weil 500 000 000 * log (500 000 000) = 4 349 485 002 Und 100 * (500 000 000/100 * LOG (500 000 000/100)) = 3 349 485 002

0
Laurent PELE