Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como a inserção do Hibernate Batch funciona?


Propriedade de hibernação hibernate.jdbc.batch_size é uma maneira de hibernar otimizar sua instrução de inserção ou atualização, enquanto o loop de liberação é sobre o esgotamento da memória.

Sem batchsize quando você tenta salvar uma entidade hibernate fire 1 insert statement, portanto, se você trabalha com uma coleção grande, para cada save hibernate fire 1 declaração

Imagine o seguinte trecho de código:
for(Entity e : entities){
session.save(e);
}

Aqui o hibernate irá disparar 1 instrução insert por entidade em sua coleção. se você tiver 100 elementos em sua coleção, então 100 instruções de inserção serão acionadas. Essa abordagem não é muito eficiente por 2 motivos principais:
  • 1) Você aumenta exponencialmente seu cache de 1º nível e provavelmente terminará em breve com um OutOfMemoryException .
  • 2) Você degrada o desempenho devido à viagem de ida e volta da rede para cada declaração.

hibernate.jdbc.batch_size e o loop de descarga têm 2 propósitos diferentes, mas são complementares.

O Hibernate usa o primeiro para controlar quantas entidades estarão em lote. Sob a capa Hibernate use java.sql.Statement.addBatch(...) e executeBatch() métodos.

Então hibernate.jdbc.batch_size diz ao hibernate quantas vezes ele tem que chamar addBatch() antes de chamar executeBatch() .

Assim, definir esta propriedade não impede o esgotamento da memória.

Para cuidar da memória, você precisa liberar sua sessão regularmente e esse é o objetivo do loop de liberação.

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

você está dizendo ao hibernate para liberar e limpar a sessão a cada 100 entidades (você libera memória).

Então, agora, qual é a ligação entre os 2?

Para ser ideal, você deve definir seu jdbc.batch_size e seu parâmetro de descarga idêntico.

se você definir um parâmetro de flush mais baixo que o batch_size que você escolher, então o hibernate irá liberar a sessão com mais freqüência para que ele crie um pequeno lote até chegar ao tamanho do btach, o que não é eficiente

quando os 2 são iguais, o hibernate só executará lotes de tamanho ideal, exceto o último, se o tamanho da coleção não for um múltiplo do seu batch_size.

Você pode ver o seguinte postar para mais detalhes sobre este último ponto