InnoDB schneller einfügen


8

Ich bin ein Doktorand, der mit Mondrian OLAP OLAP erforscht. Daher möchte ich beim ersten Laden Daten schneller in InnoDB (MySQL 5.5) einfügen. In dieser Umgebung bin ich der einzige Benutzer, daher denke ich, dass ich lockerere Einstellungen für die Einfügegeschwindigkeit zulassen kann. Im Moment verwende ich die folgenden Techniken.

  • deaktivieren log_bin
  • aktivieren skip-innodb-doublewrite
  • gesetzt transaction_isolationzu READ-COMMITTEDoder READ-UNCOMMITTED(eigentlich READ-COMMITED)
  • gesetzt innodb_flush_log_at_trx_commitzu 0oder 2(eigentlich 0)
  • innodb_buffer_pool_sizeauf 5 GB eingestellt (System verfügt über 6 GB RAM)

Gibt es weitere Techniken zum schnelleren Einfügen in InnoDB? Und muss ich ändern innodb_io_read_threadund innodb_io_write_thread? Wenn Sie weitere Informationen benötigen, teilen Sie mir dies bitte mit.

Antworten:


9

VORSCHLAG # 1

Wenn Ihr Computer über mehrere Kerne verfügt, müssen Sie Folgendes erhöhen:

[mysqld]
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000

Was ist das?

  • innodb_read_io_threads - Die Anzahl der E / A-Threads für Lesevorgänge in InnoDB.
  • innodb_write_io_threads - Die Anzahl der E / A-Threads für Schreibvorgänge in InnoDB.
  • innodb_io_capacity - Eine Obergrenze für die E / A-Aktivität, die von den InnoDB-Hintergrundaufgaben ausgeführt wird, z. B. das Löschen von Seiten aus dem Pufferpool und das Zusammenführen von Daten aus dem Einfügepuffer.

VORSCHLAG # 2

Um Daten und Indizes vom Systemtabellenbereich (ibdata1) zu trennen, müssen Sie eine vollständige Umstrukturierung von InnoDB durchführen. Klingt kompliziert, ist aber sehr einfach. Ich habe darüber im DBA StackExchange (29. August 2012) und im StackOverflow (29. Oktober 2010) geschrieben . Die grundlegenden Schritte sind

  • Lauf SET GLOBAL innodb_fast_shutdown = 0;
  • mysqldump alle Daten in einen SQL-Dump
  • service mysql stop
  • Löschen Sie die folgenden Dateien
    • ibdata1
    • ib_logfile0
    • ib_logfile1
  • service mysql start

Fügen Sie service mysql startdiese Zeile vor dem Ausführen zu hinzumy.cnf

innodb_open_files=32768

Auf diese Weise gibt es Dateihandles für jede einzelne Tabelle. Der Standardwert ist 300. Es ist bekannt, dass Dateihandles zwischengespeichert werden. Es wird eine Verlangsamung geben, wenn Sie diese sehr hoch einstellen und schnell an die Decke stoßen . Dies sollte nicht der Fall sein, wenn Sie eine kleine Anzahl von Tabellen bearbeiten.


Vielen Dank für Ihre Vorschläge. Ich werde Vorschlag # 2 jetzt versuchen, und ich werde anzupassen innodb_read_io_threads, innodb_write_io_threadsund `innodb_io_capacity‘.
Inohiro

"Lösche die folgenden Dateien ibdata1" Meine Güte, ohne Warnung.
Magallanes

6

Es gibt ein ganzes Dokument zu Bulk - Laden von Daten in InnoDB gewidmet ist . Die Haupt-Punkte:

  1. Deaktivieren Sie die automatische Festschreibung, um ein zusätzliches Löschen des Protokolls für jede Einfügeanweisung zu vermeiden: SET autocommit=0;...sql import;COMMIT;
  2. Deaktivieren Sie fremde und eindeutige Prüfungen (Sie können nicht alle Indizes vollständig deaktivieren):

    SET unique_checks=0;
    SET foreign_key_checks=0;
  3. Setzen Sie innodb_autoinc_lock_mode möglicherweise auf 2 anstelle von 1 (Standardeinstellung). Hier ist die Dokumentation zu dieser Einstellung.

Der dritte kann Ihnen helfen oder auch nicht. Ich empfehle daher, diesen Link zu lesen, um zu sehen, wie Sie die Daten anfänglich laden. Wenn Sie beispielsweise die Lasten in mehrere Einfügungen aufteilen, um sie gleichzeitig auszuführen, können Sie den Wert auf jeden Fall auf 2 setzen. Wenn Sie eine große mehrzeilige Einfügung ausführen, wird dies nicht viel (wenn überhaupt) bewirken Hilfe.

Da Sie das Binärprotokoll für diese erste Einfügung deaktivieren, sollten Sie sich nicht um die Lücken in den automatischen Inkrementierungsnummern kümmern (wenn Sie gleichzeitig Einfügungen durchführen).


Vielen Dank für Ihre Antwort! Bulk Insert sieht so schnell aus und ich werde es später versuchen.
Inohiro

Nur das Setzen von Autocommit = 0 wurde um Größenordnungen erhöht. Vielen Dank!
Alex Barker

1

Sie können die folgenden Methoden verwenden, um Einfügungen zu beschleunigen:

  • Wenn Sie mehrere Zeilen gleichzeitig vom selben Client einfügen , verwenden Sie INSERTAnweisungen mit mehreren VALUESListen, um mehrere Zeilen gleichzeitig einzufügen. Dies ist erheblich schneller (in einigen Fällen um ein Vielfaches schneller) als die Verwendung separater einzeiliger INSERTAnweisungen. Wenn Sie einer nicht leeren Tabelle Daten hinzufügen, können Sie die Variable batch_insert_buffer_size optimieren, um das Einfügen von Daten noch schneller zu machen.
  • Verwenden Sie beim Laden einer Tabelle aus einer Textdatei LOAD DATA INFILE. Dies ist normalerweise 20-mal schneller als die Verwendung von INSERTAnweisungen. Sehen
  • Nutzen Sie die Tatsache, dass Spalten Standardwerte haben. Werte nur explizit einfügen, wenn der einzufügende Wert vom Standardwert abweicht. Dies reduziert die Analyse, die MySQL durchführen muss, und verbessert die Einfügegeschwindigkeit.
  • In Abschnitt 9.5.5, „ Laden von Massendaten für InnoDB-Tabellen “ finden Sie Tipps zu InnoDB-Tabellen.

0

Plan A: "Batch" INSERTs - mehrere Zeilen pro INSERT-Anweisung. Schlagen Sie ungefähr 1000 Zeilen pro Anweisung vor. autocommit = on, kein explizites BEGIN ... COMMIT

Plan B: DATEN LADEN

Wenn Sie zu viele Zeilen gleichzeitig einfügen, muss InnoDB mehr Arbeit leisten, um die Einfügung bei einem Absturz zurücksetzen zu können. Aus diesem Grund bin ich mit autocommit = off nicht einverstanden, wodurch der gesamte Satz in einer einzigen Transaktion zusammengefasst würde.

LOAD DATA des gesamten Satzes von Zeilen hätte möglicherweise das gleiche Problem, ist aber recht schnell.

buffer_pool = 5G von 6G stehen kurz davor, zu groß zu werden. Wenn getauscht wird, sinkt die Leistung.

Eine Partitionierung würde es wahrscheinlich langsamer machen.

SHOW CREATE TABLE - Sekundärschlüssel können ein ernstes Handicap sein.

Verwenden Sie InnoDB? oder XtraDB?


Vielen Dank für Ihre Antwort. Ich benutze InnoDB. Ich bevorzuge Plan A gegenüber Plan B. LOAD DATASieht so schnell aus, aber wir müssen Daten sofort als CSV in Text schreiben und dann LOAD DATArichtig verwenden? / Ich werde das buffer_pool_sizeauf 4 GB einstellen .
Inohiro
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.