it-swarm.com.de

InnoDB benötigt über eine Stunde, um die 600-MB-Datei MyISAM in wenigen Minuten zu importieren

Ich arbeite derzeit an der Erstellung einer Umgebung zum Testen der Leistung einer App. Ich teste mit MySQL und InnoDB, um herauszufinden, was uns am besten helfen kann. In dieser Umgebung bereiten wir die Datenbank automatisch vor (laden vorhandene Dumps) und instrumentieren unsere Testtools.

Ich bereite mich darauf vor, den gleichen Daten-Dump mit MySQL und InnoDB zu testen, aber ich schaffe es bereits nicht, den anfänglichen Import für den InnoDB-Teil auf eine brauchbare Geschwindigkeit zu bringen. Der erste Dump hat länger gedauert, aber das hat mich noch nicht interessiert:

$ for i in testdb_myisam testdb_innodb; do time mysqldump --extended-insert $i > $i.sql; done

real    0m38.152s
user    0m8.381s
sys     0m2.612s

real    1m16.665s
user    0m6.600s
sys     0m2.552s

Die Importzeiten waren jedoch recht unterschiedlich:

$ for i in  testdb_myisam testdb_innodb; do time mysql $i < $i.sql; done

real    2m52.821s
user    0m10.505s
sys     0m1.252s

real    87m36.586s
user    0m10.637s
sys     0m1.208s

Nach Recherche kam ich zu Das Wechseln der Tabellen von MyISAM zu InnoDB verlangsamt das System und verwendete dann set global innodb_flush_log_at_trx_commit=2:

$ time mysql testdb_innodb < testdb_innodb.sql

real    64m8.348s
user    0m10.533s
sys     0m1.152s

IMHO immer noch schockierend langsam. Ich habe auch log_bin Für diese Tests deaktiviert und hier ist eine Liste von alle MySQL-Variablen .

Muss ich diese langen InnoDB-Zeiten akzeptieren oder können sie verbessert werden? Ich habe die volle Kontrolle über diesen MySQL-Server, da er nur für diese Testumgebung bestimmt ist.

Ich kann spezielle Konfigurationen nur für den ersten Import anwenden und sie für Anwendungstests zurücksetzen, damit sie besser zu den Produktionsumgebungen passen.

Update:

Aufgrund des Feedbacks habe ich die automatische Festschreibung und die verschiedenen Überprüfungen deaktiviert:

$ time ( echo "SET autocommit=0; SET unique_checks=0; SET foreign_key_checks=0;" \
; cat testdb_innodb.sql ; echo "COMMIT;" ) | mysql testdb_innodb;date

real    47m59.019s
user    0m10.665s
sys     0m2.896s

Die Geschwindigkeit verbesserte sich, aber nicht so sehr. Ist mein Test fehlerhaft?

Update 2:

Ich konnte auf eine andere Maschine zugreifen, da der Import nur ca. 8 Minuten dauerte. Ich habe die Konfigurationen verglichen und die folgenden Einstellungen auf meine MySQL-Installation angewendet:

innodb_additional_mem_pool_size = 20971520
innodb_buffer_pool_size = 536870912
innodb_file_per_table
innodb_log_buffer_size = 8388608
join_buffer_size = 67104768
max_allowed_packet = 5241856
max_binlog_size = 1073741824
max_heap_table_size = 41943040
query_cache_limit = 10485760
query_cache_size = 157286400
read_buffer_size = 20967424
sort_buffer_size = 67108856
table_cache = 256
thread_cache_size = 128
thread_stack = 327680
tmp_table_size = 41943040

Mit diesen Einstellungen bin ich jetzt auf ca. 25 Minuten runter. Noch weit weg von den wenigen Minuten, die MyISAM benötigt, aber es wird für mich immer nützlicher.

58
mark

Haben Sie die Bulk Data Loading Tips aus den InnoDB Performance Tuning Tips (insbesondere) ausprobiert? der erste):

  • Stellen Sie beim Importieren von Daten in InnoDB sicher, dass in MySQL der Autocommit-Modus nicht aktiviert ist, da hierfür für jede Einfügung ein Protokoll auf die Festplatte geschrieben werden muss. Um die automatische Festschreibung während des Importvorgangs zu deaktivieren, müssen Sie sie mit den Anweisungen SET autocommit Und COMMIT umgeben:

    SET autocommit=0;
    ... SQL import statements ...
    COMMIT;
    

    Wenn Sie die mysqldump-Option --opt Verwenden, erhalten Sie Dump-Dateien, die schnell in eine InnoDB -Tabelle importiert werden können, auch ohne sie mit SET autocommit Und COMMIT Aussagen.

  • Wenn Sie UNIQUE Einschränkungen für Sekundärschlüssel haben, können Sie den Import von Tabellen beschleunigen, indem Sie die Eindeutigkeitsprüfungen während der Importsitzung vorübergehend deaktivieren:

    SET unique_checks=0;
    ... SQL import statements ...
    SET unique_checks=1;
    

    Dies spart bei großen Tabellen viel Festplatten-E/A, da InnoDB seinen Einfügepuffer verwenden kann, um sekundäre Indexdatensätze in einem Stapel zu schreiben. Stellen Sie sicher, dass die Daten keine doppelten Schlüssel enthalten.

  • Wenn Ihre Tabellen Einschränkungen von FOREIGN KEY Aufweisen, können Sie den Import von Tabellen beschleunigen, indem Sie die Fremdschlüsselprüfungen für die Dauer der Importsitzung deaktivieren:

    SET foreign_key_checks=0;
    ... SQL import statements ...
    SET foreign_key_checks=1;
    

    Dies kann bei großen Tabellen eine Menge Festplatten-E/A einsparen.

IMO, das ganze Kapitel ist es wert, gelesen zu werden.

129
Pascal Thivent

Haben Sie versucht, eine Transaktion von Anfang an zu starten und am Ende zu bestätigen? Von der Frage, die Sie verknüpft haben : "Ändern Sie den Schritt" Daten einfügen ", um eine Transaktion am Anfang zu starten und am Ende zu bestätigen. Sie werden eine Verbesserung erhalten, I garantiere es. "

Denken Sie daran, dass InnoDB transaktional ist, MyISAM jedoch nicht. Transaktions-Engines behandeln jede Anweisung als eine einzelne Transaktion, wenn Sie die Transaktion nicht explizit steuern. Das kann teuer werden.

5
T.J. Crowder

Ich fand die Festplatte als Engpass - altmodische Festplatten sind hoffnungslos, SSD ist in Ordnung, aber noch lange nicht perfekt. Das Importieren in tmpfs und das Kopieren der Daten geht viel schneller, Details: https://dba.stackexchange.com/a/89367/56667

2
egmont

Ich hatte Probleme beim Massenimport und empfehle die akzeptierte Antwort. Ich habe festgestellt, dass Sie die Dinge auch erheblich beschleunigen können, indem Sie:

  1. Löschen aller Indizes (außer Primärschlüssel), Laden der Daten und erneutes Hinzufügen von Indizes
  2. Überprüfen Sie Ihre innodb_log_file_size * innodb_log_files_in_group ist ausreichend, um das Beschreiben der Festplatte in Sekundenbruchteilen zu vermeiden

In Bezug auf # 2 werden die Standardeinstellungen von 5M * 2 auf einem modernen System nicht ausreichen. Für Details siehe innodb_log_file_size und innodb_log_files_in_group

1
KCD