Lentidão ao importar centenas de registros utilizando JPA

Boa tarde amigos do GUJ,

Estou com um problema em particular que não encontro solução, e já realizei diversas buscas sobre o tema, possuo um arquivo em formato TXT, o qual preciso incluir dentro de um banco de dados, porem esse arquivo embora simples, represente uma estrutura complexa, de nodos alinhados, a estrategia adotada foi a leitura deste, atribuindo seus respectivos valores e dados a objetos mapeados do banco de dados, para reduzir a complexidade da importação.

Sendo assim primeiramente a aplicação lê o arquivo, e posteriormente atribui a um objeto todos os valores obtidos, e o objeto apos estar valorado, e persistido de forma integral, para poucos registros ao em torno de 15.000 a aplicação se comporta bem, porem quando importamos algo em torno de 100.000, a mesma demora horas.

Estamos utilizando uma base de dados MySql 5, com JPA 2, utilizando hibernate como framework de persistência, obtive muitas informações a respeito da persistência de milhares de registros utilizando o hibernate, com stateless session, ou até mesmo com JDBC puro, porem desta forma perderíamos muito do que já foi feito, inclusive as vantagens da utilização de um framework de ORM, vocês já passaram por tais situações? acham completamente inadequado utilizar JPA ou qualquer outra ferramenta de ORM para esse fim?

Agradeço muito a contribuição e colaboração de todos amigos.

Abraços.

Tente fazer uns testes com JDBC.

O gargalo está no banco mesmo?

Você chegou a ativar o hibernate statistics?

Tem um post legal no blog da caelum que pode te ajudar

Abraço

Boa tarde. Já passei por isso utilizando o mysql em um projeto que trabalhei no ano passado. No arquivo em anexo tem uma planilha com os testes que eu fiz trocando as implementações (jpa puro, jdbc puro, query nativa executada pelo jpa e query nativa deninida com anotações e executada pelo jpa). No projeto nós utilizamos o jpa 1.0 com o eclipselink como implementação. Pela planilha você pode ver que o jpa é bem mais lento. Nas partes críticas do sistema, nós trocamos a implementação utilizando queries nativas definidas com anotações (a opção que tem a melhor performance na planilha). Depois disso um pessoal especialista em mysql fez um tunning no servidor mysql. Eles mudaram vários parâmetros do mysql que, segundo eles, interferem e muito na performance. Eu não sei os detalhes sobre estes parâmetros, mas após esta mudança, ocorreu uma melhora considerável na aplicação, porém para casos de importação de dados com muitos registros o problema continuou (teve uma melhora porém continuou lento), independente das alterações no código e na configuração do servidor. Se você procurar na internet (digita mysql insert too slow no google) vai ver que várias pessoas reclamam da performance do mysql para muitos inserts, principalmente se você utiliza o InnoDB e se as tabelas possuem muitas regras de integridade referencial e índices (que podem ser reconstruídos logo após o insert e interferem na performance). A solução que possui a melhor performance é você fazer vários inserts de uma vez. Exemplo:

ao invés de:

insert into table(campo1,campo2) values(1,1);
insert into table(campo1,campo2) values(2,2);
insert into table(campo1,campo2) values(3,3);
insert into table(campo1,campo2) values(4,4);

você faz

insert into table(campo1,campo2) values
(1,1),(2,2),(3,3),(4,4);

No caso de importações com grande volume de dados, a melhor alternativa após todos os testes que fizemos foi gerar estes inserts utilizando a sintaxe acima e passando a query nativa para o jpa mesmo. Se são muitos dados, então pode ser feito gerando de 100 em 100, por exemplo.

Até mais!

Outra coisa que esqueci de falar, a ajuda do pessoal que conhecia bem as configurações do mysql (os dbas especialistas no mysql) foi extremamente importante para resolver esse problema… Acho que sem eles nós não teríamos conseguido resolver, já que eles que nos falaram várias coisas sobre a configuração do mysql e que resultaram em melhoria de performance da aplicação como um todo…