Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment fonctionne l'insertion Hibernate Batch ?

Propriété Hibernate hibernate.jdbc.batch_size est un moyen pour hibernate d'optimiser votre instruction d'insertion ou de mise à jour alors que la boucle de vidage concerne l'épuisement de la mémoire.

Sans taille de lot lorsque vous essayez de sauvegarder une entité hibernate fire 1 insert instruction, donc si vous travaillez avec une grande collection, pour chaque save hibernate fire 1 instruction

Imaginez le morceau de code suivant :

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

Ici, hibernate déclenchera 1 instruction d'insertion par entité dans votre collection. si vous avez 100 éléments dans votre collection, 100 instructions d'insertion seront déclenchées. Cette approche n'est pas très efficace pour 2 raisons principales :

  • 1) Vous augmentez de manière exponentielle votre cache de 1er niveau et vous finirez probablement bientôt avec une OutOfMemoryException .
  • 2) Vous dégradez les performances en raison d'un aller-retour réseau pour chaque instruction.

hibernate.jdbc.batch_size et la boucle de vidage ont 2 objectifs différents mais sont complémentaires.

Hibernate utilise le premier pour contrôler le nombre d'entités qui seront dans le lot. Sous la couverture Hibernate utilisez java.sql.Statement.addBatch(...) et executeBatch() méthodes.

Donc, hibernate.jdbc.batch_size indique à hibernate combien de fois il doit appeler addBatch() avant d'appeler executeBatch() .

Par conséquent, la définition de cette propriété ne vous empêche pas d'épuiser la mémoire.

Afin de prendre soin de la mémoire, vous devez vider votre session régulièrement et c'est le but de la boucle de vidage.

Lorsque vous écrivez :

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

vous dites à hibernate de vider et d'effacer la session toutes les 100 entités (vous libérez de la mémoire).

Alors quel est le lien entre les 2 ?

Pour être optimal il faut définir votre jdbc.batch_size et vos paramètres de rinçage identiques.

si vous définissez un paramètre de vidage inférieur à la taille de batch que vous choisissez, l'hibernation videra la session plus fréquemment afin de créer un petit lot jusqu'à ce qu'il atteigne la taille de btach, ce qui n'est pas efficace

lorsque les 2 sont identiques, hibernate n'exécutera que des lots de taille optimale, sauf pour le dernier si la taille de la collection n'est pas un multiple de votre batch_size.

Vous pouvez voir ce qui suit poster pour plus de détails sur ce dernier point