PL/Sql ou Java?

Boa noite Colegas !

Estou com um problema para resolver… uma rotina que deve recuperar 10 milhões de registros de uma tabela, executar uma série de processamentos com cada um deles, chegar a um resultado para cada um e gravar numa tabela no banco de dados.

Nesse processamento é necessário realizar consultas em outras tabelas.

O banco de dados é Oracle.

Minha dúvida é: crio uma classe que recupere todos os 10 milhões de registros, faça as consultas nas outras tabelas e depois grave cada resultado, tudo no Java ou devo optar por trabalhar com uma procedure em PL/Sql no próprio banco ?

Atualmente esse processamento todo esta demorando demais para ser executado e estou buscando alternativar para melhorar a performane…

Obrigado a todos.

Um abraço.

Eu faria isso no banco direto.
Se vc fizer usando java primeiro vc vai executar uma p* query pesada pra buscar 10 milhoes de registros. Depois vc vai ter que percorrer os 10 milhoes de registros 1 a 1 executando mais queries no banco e outras operacoes que vc disse que precisa fazer pra so depois disso gravar numa tabela no banco.
Agora que eu to trabalhando com .NET/C#/MSSQL tive que fazer umas (desculpa dizer isso) stored procedures hehe, e cara acho que nao faz sentido nenhum criar procedures pra simples pesquisas, mas pra processamentos pesados acho que eh uma mao-na-roda.
Eu nao conheco PL/SQL mas no meu caso eu acho o TSQL um pouco limitado e as vezes eh muito dificil fazer algo mais sofisticado.
Enfim eu faria em PL/SQL.

Se vc esta buscando alternativas para melhorar a performane, sem dúvidas PL/SQL…

Eu trabalho com Oracle e Java, eu faria em PL/SQL creio que nesse caso será a melhor alternativa.
Se a rotina pesar muito no banco peça para o DBA analisar os pontos de gargalho para você trata-los a fim de melhorar a performance e em casos mais extremos a contratação de um especialista em Tuning também é aconselhável.

Já resolvi n^20 problemas de performace em rotinas complexas utilizando Stored Procedures. Não gosto de abusar do uso delas mas creio que este seja um caso típico para utilizar.
Se o problema é desempenho, creio que a solução é por aí.

Boa tarde Colegas !

Obrigado a todos !
Valeu pelas dicas.

[]s

Boa madrugada Colegas !

Já optei por PL/SQL, mas ainda estou penando para melhorar a performance da proc que terá que varrer os 10 milhões de registros.

Como era de se esperar, o maior custo da proc é carregar o cursor com os 10 milhões…
Talvez a idéia seja idiota, mas me ocorreu se eu teria ganho se ao invés de rodar uma única proc que buscasse todos os registros, processasse um a um e inserisse na tabela com o resultado eu criasse por exemplo, dez ou vinte procs que rodariam em paralelo, cada uma pegando um quantidade de registros, processando e gravando o resultado…

Pensei nisso porque eu imaginei que seria como se tivesse 20 usuários inserindo dados simultameamente num sistema, o que me parece um número bem pequeno, então cada proc seria como um usuário.

Ainda como argumento, a tabela onde os resultados são gravados é utilizada depois para gerar arquivos de saída, ela não possui nenhum indice ou consistência que pudesse onerar a insersão simultanea.

Para ficar mais claro: a proc recupera os 10 milhões de registros de uma tabela, processa cada um deles e os insere nessa outra tabela que é utilizada então para a geração dos arquivos de saída…

Se puderem opinar a respeito…

Obrigado a todos.

[]s

Boa noite Colegas !

Alguma sugestão ?

[]s

Não conheço Oracle mas… Como está o controle de transações? Está transacionando os 10 milhões de registros para “commitar” tudo no final? Pode estar aí o gargalo, commits parciais podem ajudar.

Boa noite Colegas !

Já esta com commits parciais…

[]s

Não seria mais performatico criar uma tabela temporaria com as informacoes necessárias realizar as operações nessa temporária e realizar um update na tabela de origem baseado nesta temporária?
Pois já tive problemas de performances com cursores, e com o uso de tabelas temporárias e TSQL (no seu caso seria a PL/SQL) os resultados foram muito satisfatórios.

Por exemplo, operações com cursores que levavam em média 2 minutos, com tabelas temporarias levavam menos de 10 segundos :slight_smile:

Boa noite Colegas !

thiagovedder:

Por favor se puder analisar a situação e me dar uma luz !

Veja como tem que funcionar:

-Tenho uma tabela com os dados principais, que tem pouco mais de 10 milhoes de registros.
-Para esta operação, tenho que, para cada registro dessa tabela principal, chamar uma proc que vai fazer consultas em outras tabelas, calculos, e por fim chegar num resultado conforme a caracteristica de cada registro…
-Esse resultado, mais algumas informações do registro original eu gravo numa tabela temporaria de saida, que uso para gerar os arquivos de saida no final.
-Para evitar mais selects no meio da proc, coloquei no cursor principal todas as tabelas, sempre fazendo join através das FK´s.

Não entendi como entraria a tabela temporaria nesse caso… pode me explicar melhor ?
Ou você esta falando de fazer algo mais ou menos assim:

Insert into temporaria
Select t1.campo1, t1.campo2, t2.campo3
from tabela1 t1,
        tabela2 t2
where t1.chave = t2.chave

Depois não terei que montar um cursor usando a temporária do mesmo jeito ?

Desde já agradeço a colaboração !

Um abraço.

Oi,

Você já verificou o plano de execução desde cursor? Os joins estão corretos? Verifique se não é possível otimizar através de indices e pense na possibilidade quebrar essa consulta em muitas, pois o custo de realizar joins entre muitas tabelas (ainda mais para 10milhoes de registros) pode ser caro até mesmo para o Oracle.

Boa noite colegas !

rafaelglauber

Eu verifiquei o plano de execução… antes eu tinha um cursor e outras consultas no meio da proc.
Retirando as consultas e colocando os joins, que estão todos feitos através das PK´s ou indices uniques das tabelas, o custo do cursor aumentou muito pouco.

O custo do cursor aumentou o equivalente ao custo de uma das consultas intermediarias…

Não sei se falei, mas essa é uma rotina que já existe, mas que estou precisando otimizar urgentemente… então a realização de várias consulta no meio da proc era o modo como estava antes e ja estava demorando mais ainda…

De qualquer forma obrigado, se puderem me ajudar mais agradeço.

[]s

[quote=Zeed01]Boa noite Colegas !

thiagovedder:

Por favor se puder analisar a situação e me dar uma luz !

Veja como tem que funcionar:

-Tenho uma tabela com os dados principais, que tem pouco mais de 10 milhoes de registros.
-Para esta operação, tenho que, para cada registro dessa tabela principal, chamar uma proc que vai fazer consultas em outras tabelas, calculos, e por fim chegar num resultado conforme a caracteristica de cada registro…
-Esse resultado, mais algumas informações do registro original eu gravo numa tabela temporaria de saida, que uso para gerar os arquivos de saida no final.
-Para evitar mais selects no meio da proc, coloquei no cursor principal todas as tabelas, sempre fazendo join através das FK´s.

Não entendi como entraria a tabela temporaria nesse caso… pode me explicar melhor ?
Ou você esta falando de fazer algo mais ou menos assim:

Insert into temporaria
Select t1.campo1, t1.campo2, t2.campo3
from tabela1 t1,
        tabela2 t2
where t1.chave = t2.chave

Depois não terei que montar um cursor usando a temporária do mesmo jeito ?

Desde já agradeço a colaboração !

Um abraço.[/quote]

Seria assim mesmo, porém como o glauber disse, quebrar em inúmeras consultas e retornar para uma temporária somente os dados essenciais para a manipulação seria fundamental, inclusive para posterior manutenção.

Um pseudocódigo em T-SQL pra ver se serve pra vc.

SELECT id_usuario, nome_usuario, cidade INTO #usuariosAtivos FROM usuarios WHERE status ='A'
SELECT id_usuario, valor_lancamento INTO #lancamentos FROM lctos l JOIN #usuariosAtivos u ON u.id_usuario = l.id_usuario
UPDATE #lancamentos SET ... (operações diversas que você venha a ter).
...
..
.
DROP TABLE #lancamentos
DROP TABLE #usuariosAtivos 

Só considere verificar os indices e o plano de execução novamente para ver se existem pontos de melhoria.

kra PL/SQL na cabeça sem duvidas, converse com o administrador do banco de dados, as versões mais recentes do oracle possui alguns recursos interessantes para melhorar a performance

vlws