Olá Pessoal,
Estou gerando um relatório com o jasper, este relatório tem em torno de 4.500 páginas e está dando em torno de 70 MB. Estou escrevendo este relatório no disco para posteriormente o usuário fazer download quando o mesmo terminar de ser gerado.
O grande problema é que ele está demorando cerca de 22 minutos para gerar, isto só contando o tempo que o jasper leva para criar o pdf, não estou contando o tempo das buscas no banco de dados.
Já utilizei JRFileVirtualizer, JRSwapFileVirtualizer e ainda estou achando muito demorado, alguém já trabalhou com relatórios grandes assim?
Obrigado.
Pelo que você falou, o gargalo está na própria geração do PDF. Nesse caso, eu acho que não tem muito remédio, a não ser esperar. A única coisa que fica na minha cabeça é: o que alguém faria com um relatório de 4.500 páginas ? É um documento contábil por um acaso ?
Você tem certeza que não é banco? Já vi inúmeros casos assim e todos eram problemas de selects ou tabelas mau feitas.
Como você fez para separa o tempo do banco da geração?
Falou.
Bruno, tenho certeza absoluta que não é entre o banco, por que conto o tempo somente na geração do relatório, para isto adiciono antes de iniciar a geração pelo jasper:
long tempoInicial = System.currentTimeMillis();
E no final:
long tempoFinal = System.currentTimeMillis();
long dif = (tempoFinal - tempoInicial);
Assim sei que aquele trecho demorou tanto tempo para ser executado.
Faço isto também entre as consultas, e elas não demoram nada em comparação a geração do pdf.
rmendes08, este é um relatório para folha de ponto, e olha que ele está segmentado por setor, se fosse de todo mundo seria muito mais.
Obrigado.
Não há possibilidade de gerar esse relatório de tempos em tempos através de um processo à parte, e quando o usuário quiser ele só baixa o arquivo?
Pelo menos o acesso seria instantâneo.
Deve ser um daqueles típicos casos que o relatório existe simplesmente porque “tem que ter” 
Você esta fazendo a query por fora e passando o resultset para o jasper ou o sql esta dentro do jasper?
Hoje ele é gerado com uma Thread e fica independente da requisição, de tempos em tempos tem um ajax que vai lá e verifica se o arquivo está pronto,
mas como ele demora em torno de 22 minutos para ficar pronto, o usuário fica 22 minutos esperando com uma tela de aguarde,
se não conseguir diminuir esse tempo tenho que tentar outras alternativas como enviar por email o link do arquivo quando o mesmo ficar pronto, ou algo do tipo.
Bruno, a query é gerada fora, somente passo pra ele o JRBeanCollectionDataSource.
Sinceramente, acho que falta um pouco de análise nesse caso.
1 - Com que frequência esse relatório é gerado ?
2 - Qual a finalidade desse relatório ?
3 - O usuário que está gerando esse relatório necessita de toda essa informação ?
Veja só, estes passo são importantes. Muito provavelmente, se você gerar uma relatório separado por funcionário e limitado a 1 mês de trabalho sua vida ficará muito mais fácil. Mas como eu falei, sem responder às questões acima fica difícil. Talvez quem tenha que usar esse relatório esteja acostumado com algum sistema em Clipper que imprimia tudo em papel formulário e a pessoa saia procurando o que queria no olho …
Olá Bruno, isto ai já é questão do negócio, anteriormente cada relatório tinha em torno de 100 páginas, era tranquilo,
agora o cliente precisa dele assim com mais páginas para diminuir a iteração dele com o sistem, e todas as informações são totalmente necessárias. Como eu disse é um relatório de folha de ponto, não pode deixar de imprimir uma folha de ponto porque todos precisam assinar. Antes o usuário gerava setor por setor, agora ele quer todos os
setores de uma filial de uma só vez.
Por esse motivo ele ficou grande assim, porque no pior dos casos ele vai ter 4500 páginas (4500 folhas de ponto, uma pra cada página), tem outros casos que vai dar 100 páginas, ai vai ser tranquilo.
Obrigado.
Esclareceu e muito! Veja só, mesmo neste caso você não tem 1 relatório de 4.500 páginas. Acompanhe meu raciocínio: seu usuário deve ser um encarregado de RH que precisa imprimir a folha de ponto de cada funcionário para que cada funcionário assine o seu. Imagino que o que ele quer é clicar em 1 botão e imprimir tudo de uma vez. A provável solução foi gerar tudo em PDF. Ele teria que fazer o download e mandar para a impressora manualmente, certo ? Então, eu posso concluir que o que você tem são N relatórios de 1 a 2 páginas cada um, de forma que é inviável o cara gerar, baixar e mandar imprimir um por um.
Como eu faria: criaria um Applet para imprimir o JasperPrint diretamente, sem geração de PDF. No Applet eu teria uma lista dos funcionários para o qual eu preciso gerar as folhas de ponto. Então, para cada funcionário eu mando a requisição para gerar o relatório e na resposta eu envio para a impressora. Provavelmente o tempo total de processamento em si não vai diminuir, mas você aproveita o tempo que leva para cada relatório ser impresso para processar os relatórios em paralelo. Ou seja, o tempo total pode não diminuir tanto, mas diminui drasticamente o tempo entre o pedido do relatório é a saída da 1a página, pegou a idéia?
rmendes08, é isto mesmo, entendeu correto. O grande porem é que o cara que gera o relatório não é o mesmo que imprime, ele precisa mandar o arquivo pra gráfica para imprimir.
Fiz aqui uma configuração:
JRSwapFileVirtualizer fileVirtualizer = new JRSwapFileVirtualizer(1000, new JRSwapFile(caminhoRelatorio + "temp", 2048, 1024), false);
Na minha máquina local e no ambiente de homologação, ambos com uma base com 2300 usuários, ele gera em incríveis 3 minutos, quando mando para o servidor de produção, que é muito mais potente que minha máquina e tem 4.500 usuários, ele gera em 22 minutos, to quase mandando minha máquina pra produção (rsrsrsrsrsr).
Sei que o servidor de produção tem outros processos concorrentes, mas pela teoria ele deveria gerar em torno de 6 minutos, mas não ele está gastando quase 4 vezes mais tempo.
Bom, então o problema deve ser concorrência mesmo. Eu chutaria o seguinte, alocaria mais espaço inicial para o arquivo de swap, se no seu teste deu 70MB, aloque uns 100MB logo de uma vez. Essas realocações costumam gastar recursos consideráveis, ainda mais quando se trata de I/O. Mas nesses caso, o que vem a calhar é uma boa ferramente de profiling.
Olá Pessoal, somente para conhecimento, consegui resolver o problema. (Agora posso curtir o feriado, rsrsrs)
Como tinha dito, em homologação o relatório era gerado rapidamente, porém com uma massa de dados 50% menor, mas na produção demorava 4 vezes mais, pela lógica deveria ser apenas 2 vezes mais.
O problema é que na produção existem duas máquinas em cluster, quando eu gerava qualquer arquivo, o nó do cluster tentava sincronizar com o outro nó, por isto a demora. Agora passei a gravar em um diretório compartilhado, assim o servidor não tenta sincronizar os arquivos. Conclusão, com uma massa de dados 50% maior, está gerando no mesmo tempo que gerava em homologação, como imaginado não era problema com o jasper, mas sim de infra.
Obrigado a todos.
Galera sei que o post já esta fechado mas pesquisando achei esse link de um blog, e resolvi compartilhar aqui ele fala sobre virtualização para gerar grandes relatórios
http://www.danielsousa.com.br/wp/2010/09/12/usando-virtualizacao-para-gerar-grandes-relatorios-no-jasperreports/
Boa tarde espero ter ajudado alguma pessoa que venha ver esse post.
:lol: