JPA/Hibernate verbessern, batch-insert-Leistung
Habe ich ein Datenmodell, das hat ein EINS-ZU-VIELE-Beziehung zwischen EINEM entity und 11 anderen Personen. Diese 12 Personen zusammen repräsentieren ein Datenpaket. Das problem ich habe zu tun mit der Anzahl der Einsätze, die auftreten, auf die "viele" - Seite dieser Beziehungen. Einige von Ihnen können so viele wie 100 einzelne Werte so zu speichern, ein ganzes Datenpaket in der Datenbank es erfordert bis zu 500 Einsätze.
Ich bin mit MySQL 5.5 mit InnoDB-Tabellen. Jetzt, nach dem Test der Datenbank sehe ich, dass es leicht tun können, 15000 inserts pro Sekunde bei der Verarbeitung einer Batchdatei einfügen (und auch nicht mehr mit DATEN zu LADEN, aber das ist nicht praktikabel für diesen Fall).
Gibt es eine Möglichkeit, einen Haufen von diesen einzelnen 500 Einsätze in, sagen wir - 5 Einsätze mit 100-WERTE (für den 5 verlinkten Personen, jeder hat 100 Werte) mit Hibernate?
Als Angefordert:
@OneToMany(mappedBy="beat", cascade=CascadeType.ALL)
@OrderBy("miliseconds ASC")
public List<AmbientLight> lights;
Ich sollte wohl auch erwähnen, eine wichtige information - ich bin mit Spielen! Rahmen 1.2.3
Ich habe aktualisiert die original-Beitrag. Das Problem ist höchstwahrscheinlich die Tatsache, dass für jedes LICHT-Objekt wird erzeugt es eine INSERT-Anweisung (und das gleiche für 6 andere Objekte), so landet es dabei über 500 Einzel-inserts in einer Transaktion.
Ich glaube, es sollte kein performance-problem, dass, wenn Sie es nicht tun, dass in so vielen Threads. vielleicht können Sie versuchen, legen Sie die batch-parameter "Größe"? oder verwenden Sie
.createNativeQuery()
stattdessen, wenn Sie, was sql ist schneller und es lohnt sich.Ja, ich bin mir bewusst, eine native Abfrage könnte schneller sein, aber ich freue mich gar nicht darauf schreiben nativer Abfragen für die 11 Personen, die verlinkt sind auf diese Weise! Auch, tun 500 Einsätze in der gleichen Tabelle wird IMMER langsamer sein als ein Einsatz mit 500-Werte. (INSERT INTO .... WERTE ( ), ( ), ( ), .... )
wie über die batch-parameter "Größe"? zumindest können Sie speichern einige roundtrip zur Datenbank. kannst du deinen code einfügen, der Entität?
InformationsquelleAutor Iv4n | 2013-07-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Habe ich es geschafft, zu lösen dieses problem durch die Verwendung von Hibernate-Sessions für jede "Gruppe" von Einsätzen. Die Ergebnisse sind über eine 7-fache Verringerung in der Zeit benötigt, um die Daten zu speichern. Verwendet, um etwa 2000ms zu sparen ein 'Paket' und jetzt dauert es zwischen 200ms und 300ms, das gleiche zu tun.
Nur wiederholen - das gilt für Spielen! Rahmen 1.2.3 - ich bin nicht sicher, ob, oder wie das gilt auch für andere frameworks oder Applikationen, Hibernate.
'InitializeFromJsonAndSave' - Methode wurde so geändert, dass anstelle des Aufrufs des Objekts speichern() Methode, Anrufe mySession.speichern(myNewObject).
Haben Sie Vorschläge, wie weiter zu verbessern-und dies ohne die Abkommen zu weit außerhalb des typischen Spielen! Rahmen Zwängen?
Wenn die Leistung ist ok für Sie, können Sie bleiben mit dieser Lösung. Die andere Verbesserung, die Sie haben können, ist die Trennung von Ihrem commit in mehrere Transaktionen statt Spül-und clearing-hibernate-session. Eine einfache Möglichkeit, dies zu tun mit spielen ist eine Job. Ihre Aufgabe nehmen Sie zum Beispiel 100 Objekte iterieren über Sie und Begehen. In dem controller können Sie starten mehrere Jobs parallel aus, bei denen die Reihenfolge egal ist, und warten Sie, bis alle jobs zu kündigen, die in Ihrem controller
InformationsquelleAutor Iv4n
Hier sind zwei gute Antworten auf das Thema
Beachten Sie, dass mit Identität generator (generator verwendet standardmäßig mit spielen) batch einfügen deaktiviert ist.
Ja tut es, sehen, spielen.db.jpa.Model-Klasse
InformationsquelleAutor Seb Cesbron