Spezifischen MySQL-bulk-Einfügung performance-tuning

Ich weiß, diese Frage wurde gebeten, über und über. Dies ist jedoch eine sehr spezifische Frage für ein sehr spezifischen Szenario. Hoffentlich werden Sie in der Lage, mir zu helfen.

Betreibe ich eine Datenbank für die Protokollierung, mit über 10 Tabellen. Die Haupt-Tabelle, welche den aktuellen log-Einträge hat etwa 30 Felder, von denen 5 durchsucht werden. Ich würde sagen, die Datenbank ist seit kurzem mittlerer Größe, wie erreichen wir 200 Millionen Einträge in dieser Tabelle. Andere Tabellen speichern gemeinsamer Daten, von denen der größte hat 4 Felder, die alle durchsucht werden, ist mit fast 1 million Einträge. Alle anderen Tabellen enthalten weniger als 100 tausend Datensätze, die jeweils.

Einsätze kommen in spikes. Ich bekomme die logs vom Vortag in (ganz schlecht formatierte csv-Dateien jeden Tag um 2 UHR, und ich habe bis 8 UHR und legen Sie (etwa 20 Dateien, 100 tausend Zeilen jeder) in die Datenbank. Dann bekomme ich nur sehr wenige wählt (vielleicht einige 1000 pro Tag) während der Arbeitszeit. Dann Spülen und wiederholen.

Den SELECT-Abfragen sind Recht einfach, denn Sie bestehen meist aus einem oder zwei joins mit einer oder zwei Gruppen VON Aussagen. Die Menschen, die suchen Sie in dieser Datenbank wollen sofortige Ergebnisse, so habe ich 5 multi-Spalten-Indizes in der Haupttabelle, die helfen, die genauen Recherchen, die ich habe, und derzeit WÄHLEN Sie Leistung ist sehr gut. Keine Abfrage hat mehr als 0,1 Sekunden so weit. Es gibt einige Berichte, aber diese dauert etwa 10 Sekunden, zu erzeugen, und das ist akzeptabel.

Derzeit habe ich ein C Programm, das ich schrieb zu Lesen der Daten aus der CSV-Dateien, reinigen Sie es, und legen Sie Sie in Chargen von 1000 Zeilen pro INSERT-Abfrage. Diese Einsätze sind nicht ganz dumm, weil ich auf die gemeinsamen Daten zu sehen, wenn er schon auf die anderen Tische, legen Sie es, wenn es nicht, und cache, wenn es ist. Es gibt mir auch die performance-Daten in form von, wie viele Datensätze es einsetzen pro Sekunde. Dieses Programm ist sehr schnell, und ohne das senden der Daten in der Datenbank, erhalte ich rund 100 tausend Zeilen pro Sekunde. Natürlich, dieses Programm und die Datenbank liegen auf dem selben physischen Rechner.

Nun, die Daten, die ich bekommen jeden Tag wächst linearily, und die Leistung der Einlagen sinkt logarithmisch. Die gestrigen Daten dauerte 5 Stunden und eine Hälfte zu legen, auf etwa 400 Zeilen-Einträge pro Sekunde.

Habe ich einige benchmark-Daten durch einfügen der ersten 1 million Zeilen mit unterschiedlichen Konfigurationen in eine leere Datenbank, und das ist ziemlich viel, was ich habe:

MyISAM-Tabellen: beginnt bei 1500 Zeilen pro Sekunde, verringert sich logarithmisch auf rund 700 Zeilen, die pro Sekunde durch die Zeit, es wird die 1-millionste Zeile
InnoDB-Tabellen: wie MyISAM, nur rund 100 Zeilen pro Sekunde schneller
InnoDB mit allen Indizes deaktiviert, auf die Haupt-Tabelle: beginnt bei 2100 Zeilen pro Sekunde, sinkt bis auf 1000 Zeilen pro Sekunde.
InnoDB Indizes, die mit dem Dateisystem montiert mit Rückschreiben von Daten (ext3): das gleiche wie InnoDB, nur leicht aber fast unmerklich schneller.

innodb_buffer_pool_size ist festgelegt 1000MB

Vermeidung von index-Erstellung keine option, aber es ist offensichtlich, dass es eine große Wirkung in der Leistung. Allerdings brauche ich viel schneller Einsätze. Wie die Daten zeigen, dass Einsätze länger dauern, da die Datenbank wächst, so wie die Daten, die ich bekomme, ist jeden Tag größer, ich brauche einen gewaltigen Sprung in der performance von Gewindeeinsätzen. Wenn ich könnte es 10000 inserts pro Sekunde oder mehr sind, wäre es wirklich toll.

System monitor sagt mir meine wichtigste Ressource Verbrauch ist die disk-I/O, die geht fast bis zu 100% beim einsetzen. Weil das so ist, brauche ich eine extrem schnelle Möglichkeit zum einfügen von Daten. Meine theoretische Grenze ist, dass der SATA-bus, aber das ist noch ziemlich weit Weg. Die Speicherauslastung scheint es nicht zu sein, dass hoch bei 20% (oder MySQL ist nicht mit Speicher korrekt)

Um dies zu erreichen, ist es akzeptabel, zu erstellen Sie die Datenbank, die im Laufe von mehreren Tagen, und dann hot-swap aus der reader-Anwendung, ist es akzeptabel, zum ändern einer Einstellung im OS und MySQL, ist es akzeptabel, um Arbeitsspeicher zu erweitern, wenn erforderlich. Es ist auch akzeptabel, ändern Sie die Struktur der Datenbank, wenn nötig.

So, ich bin wirklich offen für Ideen hier. Niemand weiß von irgendetwas, was mir helfen könnte?

Edit: ich bin derzeit daran, das einfügen der neuen Zeilen in eine Tabelle im SPEICHER, und führen Sie dann ein WÄHLEN Sie IN der realen Tabelle. Hoffentlich, es wird nur ein update und Spülen Sie den index, nachdem alle Zeilen eingefügt wurden. Ich werde versuchen, dies am Montag. Hat jemand versucht, so etwas wie dies vor?

InformationsquelleAutor | 2011-02-25
Schreibe einen Kommentar