high performance hibernate einfügen
Arbeite ich an einem Latenz-sensitive Teil einer Anwendung, die im Grunde erhalte ich ein Netzwerk-event die Daten transformieren, und dann legen Sie alle Daten in die DB. Nach profiling-ich sehe, dass im Grunde alle meine Zeit damit verbracht, die Daten zu speichern. hier ist der code
private void insertAllData(Collection<Data> dataItems)
{
long start_time = System.currentTimeMillis();
long save_time = 0;
long commit_time = 0;
Transaction tx = null;
try
{
Session s = HibernateSessionFactory.getSession();
s.setCacheMode(CacheMode.IGNORE);
s.setFlushMode(FlushMode.NEVER);
tx = s.beginTransaction();
for(Data data : dataItems)
{
s.saveOrUpdate(data);
}
save_time = System.currentTimeMillis();
tx.commit();
s.flush();
s.clear();
}
catch(HibernateException ex)
{
if(tx != null)
tx.rollback();
}
commit_time = System.currentTimeMillis();
System.out.println("Save: " + (save_time - start_time));
System.out.println("Commit: " + (commit_time - save_time));
System.out.println();
}
Die Größe der Sammlung ist immer kleiner als 20. hier ist die timing-Daten, die ich sehe:
Save: 27
Commit: 9
Save: 27
Commit: 9
Save: 26
Commit: 9
Save: 36
Commit: 9
Save: 44
Commit: 0
Dies ist verwirrend für mich. Ich vermute, dass die save
sollte schnell sein und alle die Zeit, die aufgewendet werden sollten commit
. aber klar, ich bin falsch. Ich habe auch versucht haben, entfernen die Transaktion (die nicht wirklich notwendig), aber ich sah mal schlimmer... ich habe den Ruhezustand.jdbc.batch_size=20...
Kann ich erwarten zu bekommen, so viele wie 500 Nachrichten/Sekunde, so brauche ich single-message-handling unter 20 Millisekunden.
ich muss diese operation so schnell wie möglich, im Idealfall gäbe es nur einen roundtrip zur Datenbank. Wie kann ich dies tun?
InformationsquelleAutor der Frage luke | 2010-06-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bewegen, Ihre primary key-generation Weg von einer server-Seite auto-Inkrement. Ihr Java-code müssen die Verantwortung für die PK-generation zu vermeiden, Rundreisen.
Für menschenwürdige bulk insert-Leistung, die Sie benötigen, eine Methode, die nicht brauchen, um zu schlagen die Datenbank auf jedem einzelnen Anruf zu saveOrUpdate. Verwendung von UUIDs als primären Schlüssel oder die Umsetzung HiLo können helfen, dies zu erreichen. Ansonsten gibt es keine bulk insert eigentlich Los ist.
Haben sowohl die performance als auch Interoperabilität mit anderen externen Systemen, die gebündelt oder die pooled-lo Optimierer die beste Wahl.
InformationsquelleAutor der Antwort Michael
Ehrlich, ich weiß nicht, was sein kann, gefolgert aus dem test und aus der "Maßnahmen" zeigen Sie uns (ich vermute viel Aufwand aus dem warm-up, die Kollektion ist sehr klein, und die Stichprobe ist sehr klein).
Jedenfalls kann ich Ihnen sagen, dass Sie Ihren aktuellen code nicht skalieren und sind Sie sehr wahrscheinlich zu explodieren, die Sitzung bei der übergabe einer größeren Sammlung. Sie müssen bündig und klar, die Tagung in regelmäßigen Abständen (je 20 Einträge, wenn die batch-Größe ist 20).
Eigentlich, ich empfehle die Lektüre des ganzen Kapitel 13. Batch-Verarbeitung.
InformationsquelleAutor der Antwort Pascal Thivent
Einige grundlegende Sachen:
Einschränkungen ohne index?
Dosierung ist Teil der JDBC 2.0 ermöglicht das ausführen mehrerer Anweisungen in einer 'batch'; die Idee ist, zu reduzieren round-trip-Latenz (führen Sie mehrere Chargen pro Transaktion).
Können Sie wahrscheinlich verwenden Sie diese als einen benchmark-test. Ich würde auch schauen, SQL, hibernate erzeugt, um zu sehen, ob es ist die Durchführung einer Abfrage pro einfügen, um die generierten Ids.
InformationsquelleAutor der Antwort Justin