2015-01-03 19 views
6

ci sono dei motivi per cui l'ibernazione di batch/hibernate.order_updates/hibernate.order_inserts sono disabilitati di default? C'è qualche svantaggio quando abiliti una dimensione batch di 50? Lo stesso vale per i parametri order_updates/order_inserts. C'è un caso d'uso in cui non dovresti abilitare queste funzionalità? Ci sono impatti sulle prestazioni quando si utilizzano queste funzionalità?Perché il caricamento in ibernazione/order_inserts/order_updates è disabilitato per impostazione predefinita?

Posso solo vedere che queste impostazioni aiutano molto quando ho bisogno di ridurre il conteggio delle query che è necessario soprattutto in un ambiente cloud con latenze elevate tra la mia applicazione e il server di database.

risposta

14

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.

+0

Grazie per la risposta. ma sfortunatamente non ho avuto l'uso di 'order_insert' e' order_update'. –

+1

@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". –