Mysql
 sql >> Database >  >> RDS >> Mysql

Come funziona l'inserto Hibernate Batch?

Iberna la proprietà hibernate.jdbc.batch_size è un modo per l'ibernazione per ottimizzare la tua istruzione di inserimento o aggiornamento mentre il ciclo di svuotamento riguarda l'esaurimento della memoria.

Senza batchsize quando si tenta di salvare un'entità ibernate fire 1 istruzione insert, quindi se si lavora con una grande raccolta, per ogni istruzione save hibernate fire 1

Immagina il seguente blocco di codice:

for(Entity e : entities){
session.save(e);
}

Qui hibernate attiverà 1 istruzione di inserimento per entità nella tua raccolta. se hai 100 elementi nella tua raccolta, 100 istruzioni di inserimento verranno attivate. Questo approccio non è molto efficiente per 2 motivi principali:

  • 1) Aumenti esponenzialmente la tua cache di 1° livello e probabilmente finirai presto con una OutOfMemoryException .
  • 2) Il rendimento è peggiorato a causa dell'andata e ritorno della rete per ogni affermazione.

hibernate.jdbc.batch_size e il ciclo di lavaggio hanno 2 scopi diversi ma sono complementari.

Hibernate usa il primo per controllare quante entità saranno in batch. Sotto la copertura Hibernate usa java.sql.Statement.addBatch(...) e executeBatch() metodi.

Quindi hibernate.jdbc.batch_size dice a Hibernate quante volte deve chiamare addBatch() prima di chiamare executeBatch() .

Quindi l'impostazione di questa proprietà non impedisce l'esaurimento della memoria.

Per prenderti cura della memoria devi svuotare la tua sessione regolarmente e questo è lo scopo del flushing loop.

Quando scrivi :

for(Entity e : entities){
if (i % 100 == 0 && i>0) {
                    session.flush();
                    session.clear();
                }
}

stai dicendo a Hibernate di svuotare e cancellare la sessione ogni 100 entità (rilasci memoria).

Quindi ora qual è il collegamento tra i 2 ?

Per essere ottimale devi definire il tuo jdbc.batch_size e il tuo parametro di lavaggio è identico.

se definisci un parametro flush inferiore a batch_size che scegli in modo ibernato cancellerà la sessione più frequentemente in modo da creare un piccolo batch fino a quando non arriva a btach size che non è efficiente

quando i 2 sono uguali, l'ibernazione eseguirà solo batch di dimensioni ottimali tranne l'ultimo se la dimensione della raccolta non è un multiplo di batch_size.

Puoi vedere il seguente post per maggiori dettagli su quest'ultimo punto