Boa tarde,
Estou testando a performance do Hibernate e tem uma coisa me deixando intrigado. Estou usando o código abaixo para incluir lotes de 1.000, 10.000 e 100.000 registros em uma tabela de clientes:
ClienteDAO clienteDAO = new ClienteDAO();
Session s = HibernateUtil.getSessionFactory().openSession();
s.beginTransaction();
clienteDAO.setSession(s);
Cliente c;
System.out.println("Início " + ));new Date(System.currentTimeMillis()
for (int i = 0; i < 100000; i++) {
c = new Cliente();
c.set…
clienteDAO.makePersistent©;
}
System.out.println("Término da inclusão " + ));new Date(System.currentTimeMillis()
s.getTransaction().commit();
System.out.println("Término do commit " + ));new Date(System.currentTimeMillis()
Vejam os resultados:
Para 1.000 registros (3 segundos)
Início Wed Apr 04 14:49:09 GMT-03:00 2007
Término da inclusão Wed Apr 04 14:49:11 GMT-03:00 2007
Término do commit Wed Apr 04 14:49:12 GMT-03:00 2007
Para 10.000 registros (22 segundos)
Início Wed Apr 04 14:49:29 GMT-03:00 2007
Término da inclusão Wed Apr 04 14:49:45 GMT-03:00 2007
Término do commit Wed Apr 04 14:49:51 GMT-03:00 2007
Para 100.000 registros (164 segundos)
Início Wed Apr 04 14:38:58 GMT-03:00 2007
Término da inclusão Wed Apr 04 14:41:15 GMT-03:00 2007
Término do commit Wed Apr 04 14:45:42 GMT-03:00 2007
O que estou achando estranho, e que fica bem claro no exemplo de 100.000 registros, é o tempo que demora para processar o commit. Ele leva 77 segundos para executar “clienteDAO.makePersistent©” para os 100.000 registros, mas depois leva 87 segundos para fazer o commit. Nestes 87 segundos, o uso de CPU do meu servidor de banco de dados é de 3% (Firebird).
As minhas dúvidas são:
- Isso é esperado?
- O Hibernate possui seu próprio controle de transações, e depois na hora do commit abre uma transação no banco e grava os registros um a um?
- Existe uma forma de melhorar esta performance?
- O Hibernate costuma ser indicado para, além de operações de CRUD, operações em lote?
Atenciosamente,
Fabiano