Estou com um problema e queria ver se alguem poderia me indicar uma melhor solução:
Tenho que fazer um select enorme com varios joins e que retorna uma media de 30 à 50 mil registros e demora mais ou menos 1h e meia pra rodar o banco é Oracle 10g, em uma aplicação JWS, JDBC, WebSphere…
Solução temporaria foi criar uma outra tabela com o resultado do select tipo “CREATE TABLE tempTable AS SELECT…etc” e depois vou paginando esses dados de mil e mil e escrevendo um arquivo DBF que é a necessidade da aplicação, este processo esta demorando em média 2:15h para rodar, mas creio que ainda não é a melhor coisa criar essa tabela temporaria
Tentei usar assim só fazendo o select normal sem criar a tebala Statement stmt = dataSource.getConnection().createStatement();
stmt.setFetchSize(1000);
ResultSet rs = stmt.executeQuery(query); mas esta demorando muitooooo mais… quase 10h então imagino que a cada mil ele esta execultando a query novamente no banco…
Tem, alguma forma de fazer isso ficar no proprio oracle, e eu trazer só de mil em mil no ResultSet e os dados ficar em cache no oracle e quando eu for ler o 1001 ele simplismente pegar no banco dessa forma ja posso ir direto escrevendo meu arquivo DBF sem Criar uma Tebala Temporaria, ganhar um OutOfMemoryError…
Sei que o que vc poderia tentar fazer é “picotar” a consulta. Tenta utilizar o between.
SELECT *
FROM CLIENTES
WHERE ID = 123
//...
BETWEEN valor1 AND valor2
Vc iria iterar sobre essa consulta e montar no seu cache. Colocaria tipo que de mil em mil. 1 … 1000, 1000 até 2000. Quando não tivesse mais resultado é pq acabou a consulta! ^^ Mas faça um intervalo que vc saiba que terá um resultado rápido, mas também não tão pequeno para não pesar seu servidor com requisições!
Crie uma lista no seu Java e armazena a moçada lá.
Q tal?
J
jc.thalys
Acontece que a query em si demora muito… se eu ficar executando ela mesmo que por partes tem muitos joins e demora mais de 1h… queria executar uma vez e depois e lendo os dados por partes. Tem como?
claudiom
apesar de parecer um número grande, 50 mil registros para o oracle não é tanta coisa assim…
não sei com quantas tabelas essa query faz join, mas para demorar 1h:30min para rodar, eu desconfiaria que seu maior problema é a própria query…
considerando que a query toma 66% do tempo total de processo, talvez otimiza-la deveria ser sua primeira aposta.
E
entanglement
No seu caso em particular, acho melhor deixar o resultado de sua query em uma tabela qualquer, para que outra aplicação possa manipular essa tabela menor (50000 registros é uma tabela minúscula) à vontade.
J
jc.thalys
claudiom:
apesar de parecer um número grande, 50 mil registros para o oracle não é tanta coisa assim…
não sei com quantas tabelas essa query faz join, mas para demorar 1h:30min para rodar, eu desconfiaria que seu maior problema é a própria query…
considerando que a query toma 66% do tempo total de processo, talvez otimiza-la deveria ser sua primeira aposta.
Concordo. Mais não tem muito o que fazer na query… ja revi aqui com o DBA e não tem muito o que fazer, por que isse é todo o histórico da empresa de 2009… teoricamente isso só deve rodar uma vez por ano… e a previsão é que em 2011 quando for gerar de 2010 isso vá para 1milhão… por isso queria tentar otimizar o máximo… Há e a query tem 21 joins…
L
leoduval
Opa… blz?
Cara eu revisaria essa query e indices dessas tabelas.
Ja tive problema com volume de informação mas não necessariamente de performance e utilizei limit na construção do sql (postgres) talvez isso possa te ajudar… espero que sim.
Abs
FacaNaCaveira
Fala ai jc.thalys
Uma das coisas que voce pode fazer é criar uma Stored Procedure no Oracle, pois após a primeira execução desta ela cria um plano de execução que é usado toda vez que ela é executada, isso economiza um tempo absurdo, toda vez que ela é executada. De repente pode ser uma boa alternativa e depois chama a procedure pelo JDBC (se for assim que vc esta usando)