2016-11-04 6 views
1

Ich habe folgendes:Was bewirkt, dass die Aktualisierung der Hibernate-Sitzung langsam ist?

public void batchSave(Iterable<T> entities) { 
    int i = 0; 

    for (T entity : entities) { 
     session.update(entity); 
     i++; 

     if (i % BATCH_SIZE == 0) { 
      session.flush(); 
      session.clear(); 
     } 
    } 

    session.flush(); 
    session.clear(); 
} 

Diese Methode 2 Mal aufgerufen wird, einmal mit einem Eingang der Größe ~ 28000 und einmal mit einem Eingang Größe ~ 32000, so dass nicht viel Unterschied in Bezug auf Größe.

Letzteres dauert jedoch viel länger zu laufen. Meine Frage ist, was würde bewirken, dass diese Funktion einmal länger als die andere Zeit läuft? Wenn alle anderen Eigenschaften zwischen den beiden gleich sind, würde ich erwarten, dass diese in ähnlicher Zeit enden.

Mein Verständnis ist, dass session.update(object) eine Aktualisierung der DB ausgibt, aber ich sollte beachten, dass in der Gruppe von 32000 fast alle Objekte ihren Status geändert haben, während für die 28000 nur etwa 5000 von ihnen haben. Trotzdem dauert die 28000er Größe vielleicht 2s, während die etwas größere für Minuten läuft.

+0

Was ist der Wert von BATCH_SIZE? Sind all diese Entitäten Instanzen der gleichen Klasse? Ändern Sie die Eigenschaften der Entitäten oder nehmen Sie Änderungen an anderen Entitäten vor, die sich auf die Entitäten in der Liste beziehen? – jspurim

+0

Dies kann nützlich sein https://www.mkyong.com/hibernate/hibernate-display-generated-sql-to-console-show_sql-format_sql-and-use_sql_comments/ – jspurim

+0

'BATCH_SIZE = 50' und die erforderlichen Ruhezustandseigenschaften eingestellt werden . Objektmodelle sind verschiedene, aber nicht komplizierte, einfache POJOs mit Strings, Integers und Doubles und tatsächlich ist die mit der kleineren Collection-Größe ein großes POJO. – mike

Antwort

0

Dies stellte sich als ein Versehen heraus, da die letzte Tabelle nicht korrekt indexiert war, so dass die Aktualisierungen bei der DB länger dauerten.

0

Dies könnte wegen auto (deferred) flushing sein. Teilen Sie sie in zwei verschiedene Transaktionen auf und die Geschwindigkeit könnte besser vergleichbar sein.

+0

Ich benutze Spring Data Repositories Muster hier, so dass dies in einer Methode verpackt ist, die mit '@ Transactional' dekoriert ist. Ist das falsch? – mike

Verwandte Themen