Geschwindigkeiten für große Chargen einfügen


10

In meiner Bewerbung scheinen meine INSERTs einen großen Teil der Zeit in Anspruch zu nehmen. Ich habe eine große Anzahl von Objekten im Speicher (~ 40-50.000), die ich in eine Tabelle einfügen möchte.

Nehmen wir eine Beispieltabelle

CREATE TABLE bill (
id BIGINT(20) PRIMARY KEY,
amount INT(11) DEFAULT 0,
bill_date DATETIME DEFAULT NOW(),
INDEX (bill_date)
) ENGINE=InnoDB

Unter Verwendung von 3 Zeilen als Stapelgröße sind die folgenden Ansätze zum Einfügen denkbar

Ansatz 1 - Konstruieren und feuern Sie 3 Roheinsätze

INSERT INTO bill (amount, bill_date) VALUES (10, '2012-01-01 00:00:00');
INSERT INTO bill (amount, bill_date) VALUES (20, '2012-01-02 00:00:00');
INSERT INTO bill (amount, bill_date) VALUES (40, '2013-02-05 00:00:00');

Ansatz 2 - Zusammenfassen der Werte zu einer Abfrage

INSERT INTO bill (amount, bill_date) VALUES 
(10, '2012-01-01 00:00:00'),
(20, '2012-01-02 00:00:00'),
(40, '2013-02-05 00:00:00');

Ansatz 3 - Feuern Sie diese Abfrage 1 Mal ab, indem Sie 6 Parameter übergeben

INSERT INTO bill (amount, bill_date) VALUES 
(?, ?), (?, ?), (?, ?);

Ansatz 4 - Diese vorbereitete Abfrage wird dreimal ausgelöst, wobei die beiden Parameter jedes Mal geändert werden

INSERT INTO bill (amount, bill_date) VALUES (?, ?);

Alle anderen Ansätze sind willkommen.

Meine Frage ist

Was ist der schnellste Weg, um mehrere Einfügungen in eine Tabelle vorzunehmen?

Ich habe diesen Link zur Geschwindigkeit des Einfügens von MySQL und diese Anleitung zur JDBC-Programmierung gelesen , kann jedoch keine Schlussfolgerung ziehen.

Mein Fall -

Derzeit hat meine Tabelle ~ 20 Spalten, von denen die meisten Zahlen sind, mit ein paar varchar (60) und 1 Textspalte. MySQL-Version 5.5. Läuft auf INNODB und hat 1 Index für Integer-Primärschlüssel. Alle Abfragen werden in Transaktion ausgeführt.

Ich erstelle meine Abfragen aus Java und verwende Spring JDBC, um die Abfragen auszuführen.

Ich verfolge derzeit Ansatz 3. Es dauert ungefähr 10 Sekunden, bis 20.000 Einfügungen in eine leere Tabelle eingefügt sind, ohne die Zeit zu berücksichtigen, die zum Erstellen der Abfrage benötigt wird.

Um die Dinge im Blick zu behalten, werden 100 bis 200 Millis benötigt, um die Daten aus der Tabelle abzurufen.

Fehlt mir etwas? Wie mache ich die Einsätze schneller?


Antworten:


3

Ziehen Sie in Betracht, Ihre Commits zu stapeln. Eine Chargengröße von 1024 ist eine gute Ausgangsgröße. Ändern Sie die Chargengrößen, bis Sie Ihren optimalen Durchsatz erreicht haben.


1

Haben Sie getestet oder wäre es möglich, Indizes für die Ziel-DB-Tabelle (n), in die Sie einfügen, zu löschen, diese in kleinere Stapelblöcke einzufügen (optimal wie oben angegeben) und dann die Indizes für die Zieltabelle (n) neu zu erstellen? Sobald alle Beilagen fertig sind? Kann leicht zu testen sein, um dies zu bestätigen.


0

Einige Tipps zum Laden von Massendaten aus MySQL-Dokumenten sind möglicherweise hilfreich. https://dev.mysql.com/doc/refman/5.6/de/optimizing-innodb-bulk-data-loading.html

Sie können die Einfügegeschwindigkeit auf verschiedene Arten erhöhen:

- turn off autocommit
- turn off unique check
- turn off foreign check

Ich hoffe das hilft !


2
Wenn Sie die Einschränkungsprüfungen (eindeutig, Fremdschlüssel, ...) deaktivieren, stellen Sie sicher, dass Ihre Daten sie nicht beschädigen oder dass sich Ihre Datenbank ab diesem Zeitpunkt in einem inkonsistenten Zustand befindet.
David Spillett
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.