In generale l'impostazione batch size
a misura ragionevole e order_insert
, order_updates
a true
può migliorare significativamente le prestazioni.
In tutti i miei progetti che uso questa configurazione come base:
hibernate.jdbc.batch_size = 100
hibernate.order_inserts = true
hibernate.order_updates = true
hibernate.jdbc.fetch_size = 400
Ma, sì, - non ci può essere memoria impatto quando si usa il dosaggio. Ma questo dipende dal driver jdbc.
Ad esempio, il driver Oracle JDBC crea buffer interni per ogni PreparedStatement
e riutilizza questi buffer. Se si chiama la semplice dichiarazione di aggiornamento, si impostano alcuni parametri con ps.setInt(1, ...)
, ps.setString(2, ...)
ecc. E Oracle converte questi valori in una rappresentazione di alcuni byte e memorizza nel buffer associato a questo PreparedStatement
e alla connessione.
Tuttavia, quando il vostro PreparedStatement
utilizza batch di dimensione 100, questo buffer sarà 100 volte più grande. E se si dispone di un pool di connessioni con exapmle 50 connessioni, ci possono essere 50 buffer di questo tipo. E se hai 100 affermazioni diverse usando il batch, tutti questi buffer possono avere un impatto significativo sulla memoria. Quando si abilita la dimensione del batch, diventa globale - Hibernate lo userà per tutti gli inserimenti/aggiornamenti.
Tuttavia, ho riscontrato che in tutti i miei progetti l'aumento delle prestazioni era più importante dell'impatto di questa memoria ed è per questo che utilizzo il batchsize=100
come predefinito.
Con order_inserts
, order_updates
, penso che questi sono disabilitati di default, perché queste impostazioni hanno senso solo se il dosaggio è acceso. Con il batching disattivato, questi ordini sono semplicemente generali.
È possibile trovare maggiori informazioni in carta bianca di Oracle:
http://www.oracle.com/technetwork/topics/memory.pdf
nella sezione "dosaggio Economico e memoria Utilizzare".
==== ==== 2016/05/31 EDIT
Una parola sulla order_inserts
e order_udpates
proprietà. consente di dire che abbiamo entità A
, B
e persistono 6 oggetti in questo modo:
session.save(A1); // added to action queue
session.save(B1); // added to action queue
session.save(A2); // ...
session.save(B2); // ...
session.save(A3); // ...
session.save(B3); // ...
dopo l'esecuzione di cui sopra:
- questi 6 oggetti ha identificatori generato
- questi 6 oggetti sono collegati alla sessione (StatefulPersistenceContext: entitiesByKey, entityEntries, ecc. /Hib.v3/)
- questi 6 oggetti vengono aggiunti ad ActionQueue nello stesso ordine: [A1, B1, A2, B2, A3, B3]
Ora, considerare 2 casi:
cassa 1:order_inserts = false
durante il flusso di sospensione fase esegui 6 inserto dichiarazioni:
ActionQueue = [A1, B1, A2, B2, A3, B3]
insert into A - (A1)
insert into B - (B1)
insert into A - (A2)
insert into B - (B2)
insert into A - (A3)
insert into B - (B3)
caso 2:order_inserts = true
, dosaggio consentito
ora, durante il flusso fase di sospensione esegui inserire 2 lotti dichiarazioni:
ActionQueue = [A1, A2, A3, B1, B2, B3]
insert into A - (A1, A2, A3)
insert into B - (B1, B2, B3)
ho studiato questo per Hibernate v3, v4 Credo Hibernate utilizza ActionQueue nello stesso modo.
Grazie per la risposta. ma sfortunatamente non ho avuto l'uso di 'order_insert' e' order_update'. –
@AmirPashazadeh Grazie per il commento. Ho aggiunto qualche esempio su come 'order_inserts' è usato per ordinare la raccolta' ActionQueue'. Lo stesso vale per "order_updates". –