Eu tenho uma consulta em JPQL que quando é executada vejo no console do eclipse que várias outras consultas são disparadas junto com a principal.
List<Object[]>resultado=query.getResultList();
É exatamente nesta linha, que dispara o JPQL, assim que passa por ela começa a rodar vários outros JPQLs. Aparentemente são várias consultas para cada linha de resultado da principal.
Gostaria de saber o que é isso e se há uma maneira de evitar, pois está onerando demais a performance.
Para piorar a situação:
Estiva lendo nos sites e descobri que este problema é chamado de N+1.
Uma das soluções seria usar “FETCH”, mas estranho a consulta já está com esta clausula.
Outra solução é separar as consultas, mas as condições para trazer os dados envolvem todas as tabelas.
Não sei se tem como separá-las
Solucao aceita
staroski
Tem situações que é melhor você escrever uma query nativa do que depender do JPA.
pmlm1 like
Essas situações são raras. A maioria dos problemas com JPA é porque as pessoas não fazem a minima ideia do que estão fazendo e colocam EAGER em todo o lado e fazem queries a obter mais do que o que precisam.
adautodasilvalima
Bom dia,
De volta com esta query.
Não foi possível por em prática a Query Nativa por questões de padrão na empresa.
Estou, trabalhando com JPA numa versão do java 7 com banco de dados ORACLE
A query está com nomes de campos e tabelas fictícios.
Se constatarem algum erro no SQL é erro que cometi ao transporta-la para cá.
Ela funciona, demora mais funciona.
Eu fui retirando tabela por tabela para saber onde estaria a demora.
Cheguei nesta: TAB_INTEGRA
Ficou só: SELECT * FROM TAB_INTEGRA
Quando entra na linha Query.ResultSet fica um tempão pensando.
Quando starta, começa a fazer outros SELECTS * “que não tem nada haver com a TAB_INTEGRA”.
Eu já ví os relacionamentos da tabela, e não tem nenhuma relacão com as que falo acima *
Já foi verificado o banco para saber se há algo errado e nada foi constatado.
O select da TAB_INTEGRA no SQLDeveloper roda de boa.
Bom devo estar pedindo que se passe um quadrado num circulo. “Impossível”.
Mas a minha esperança é que possa ser algo do tipo que alguém fale: Quando acontece isso vc
precisa alterar tal código, quero dizer, algum problema pontual que se faz quando há um comportamento desses.
Se ninguém puder dar uma opinião porque realmente é impossível, não tem problema algum porque sei que é uma sinuca de bico.
Obrigado.
pmlm
Quantas linhas tem essa tabela?
Como estão as anotações da tua classe que mapeia com a tabela TAB_INTEGRA? Há fetch EAGER?
adautodasilvalima
A tabela tem 267770 linhas das quais neste select retorna 1500 a 2000
Na classe todos os FetchType estão como LAZY
pmlm
Aqui vai retornar as 267770 linhas. No SQL developer faz fetch de apenas algumas linhas e conforme fazes scroll, faz fetch de mais. No teu código se não tens qualquer lógica de paginação vai fazer fetch de todas as linhas de uma vez. Daí o “tempão” que fica pensando.
staroski
Com todo o respeito, isso é coisa de empresa que não sabe o que faz.
adautodasilvalima
Não tem problema, a gente tem que trabalhar com as adversidades.
adautodasilvalima
Bom dia pmlm,
Esta consulta, se entendi direito sua resposta, não será apresentada na tela como resultado.
esta consulta faz parte de um JOB que roda todo dia.
A cada linha de resposta, será feito um processamento alterando esta e outras tabelas.
O limite para processar é cerca 1600 a 2100 linhas.
O problema é que pelo fato de demorar muito, acontece o timeout.
pmlm
Independentemente de apresentar na tela ou nao, estas a obter os dados da BD para a tua aplicação, certo? Tens de esperar que esses dados sejam consultados na BD e chegam a uma lista tua na aplicação.
Já verificaste se do lado da BD não há optimizações que possam ser feitas? Por exemplo criação de índices? Também vejo que a tua query inicial tem muitos “OR”. Normalmente para uma BD isso é sinónimo de maus planos de execução e longos tempos de processamento.
adautodasilvalima
Legal cara, são muito validas suas observações. Eu agradeço.
Depois posto aqui o desenrolar da bagaça.