Problema de lentidão de uma procedure
05/11/2015
0
Tenho uma procedure que rodo no Oracle usando aplicativo Delphi, onde ao criar a procedure e utilizar a sistema (Delphi), funciona perfeitamente e com um tempo muito bom.
Acontece que, no cliente, no outro dia a procedure trava na tabela que está sendo feito as inserções.
Ocorre que, se eu dropar a procedure e criá-la novamente, aí a resposta é rápida novamente.
Ou seja, quase sempre que vou usar essa procedure, pra ficar rápida, tenho que dropar e criar a procedure antes de executá-la pela aplicação.
A procedure em se, já está boa no quesito performance, mas estou com esse problema de ter que dropar e criar a procedure antes de executar as funcionalidades da mesmo pelo aplicativo.
Já tentei várias coisas, mas não consegui nenhum resultado satisfatório.
Caso alguém já passou por isso ou tenha alguma ideio, por favor me ajude.
Obrigado.
Deus abençoe a todos.
Eduardo Furtado
Post mais votado
05/11/2015
Que tipo de ferramenta de monitoramento você tem no servidor de produção ? Consegue detalhar uso de memória, caches e locks no Oracle ?
Será que a procedure não está gerando algum cache ou lock que não está sendo derrubado por algum motivo ?
A configuração do Oracle em produção é exatamente a mesma do teu ambiente de testes ?
Que tipo de ferramenta de teste de concorrência você usa ? Testou a execução da procedure com stress de concorrência ?
Qual o nivel de isolamento da procedure ? Tentou alterá-lo para um mais permissivo para ver se o problema persiste ?
Te falo isso pois, como o Fernando comentou acima, problemas de performance de procedure muitas vezes estão associados à concorrência !
É difícil de acreditar que o drop da procedure tenha algo a ver com a causa do problema... talvez, ao recriá-la, você esteja "apenas" liberando o banco de algum lock, cache ou outra coisa qualquer que ficou pendente por conta da execução anterior que travou !
Marcos P
Mais Posts
05/11/2015
Eduardo Furtado
05/11/2015
Fernando Vicari
Você já chegou a verificar se não está ficando nada com bloqueado (com lock) na tabela depois que você roda a primeira vez?
Experimenta antes de dropar fechar o delphi e a conexão pra ver se volta a ficar rápida.
Se não me engano você pode executar o SQL abaixo como admin para ver se tem lock.
SELECT DISTINCT S.SECONDS_IN_WAIT,LOCKWAIT, S.STATE, S.STATUS, S.CLIENT_INFO, S.INST_ID, S.SID SID_NUMBER, S.SERIAL#, O.OWNER BJECT_OWNER, O.OBJECT_NAME, S.OSUSER, S.MODULE, S.MACHINE, S.TERMINAL, S.PROGRAM, S.LOGON_TIME, 'ALTER SYSTEM KILL SESSION '''|| S.SID || ',' || S.SERIAL# || ''' IMMEDIATE;' KILL_TEXT FROM SYS.ALL_OBJECTS O, GV$LOCK L, GV$SESSION S WHERE O.OBJECT_ID = L.ID1 AND L.SID = S.SID AND L.INST_ID = S.INST_ID AND S.LOCKWAIT IS NOT NULL ORDER BY S.SECONDS_IN_WAIT DESC
05/11/2015
Eduardo Furtado
eu já faço essa verificação antes de executar a procedure e isso ocorre é no cliente, não é pelo Delphi. Quando está executando a aplicação no cliente.
Quando tem outra máquina ou sistema conectado em uma das tabelas já dou o aviso e não permito ele executar. Como essa rotina é de geração de livros fiscais, nesse momento não poderá ter movimentações na mesma tabela, pois aí dá concorrência, como essa geração é realmente grande, pois lê toda movimentação (Entrada e saída de notas fiscais, cupons fiscais, etc), então tem que rodar apenas em um terminal.
Obrigado.
05/11/2015
Eduardo Furtado
05/11/2015
Fernando Vicari
Na empresa trabalhamos com Delphi+Oracle e temos em média de 400 usuários no banco direto, o banco ta com mais de 2Tb de informação e não temos nenhum problema deste modo.
Aí me surge uma outra pergunta.. qual versão do Delphi você utiliza e qual componente de conexão você utiliza? Aqui trabalhamos com Delphi 2005 e conexão através do DOA.
Ou então pode ser que seja configuração do Banco. Mas daí não sou DBA para te ajudar.
06/11/2015
Eduardo Furtado
A versão do Delphi que estou usando é a 2010.
Os componentes de conexão que estava usando era TOraStoredProc, aí fizemos alguns testes e verificamos que usando o TOraScript ficava mais rápido, com isso, estamos usando o TOraScript no momento.
A questão é que realmente está travando nas tabelas de inclusão, mas isso está ocorrendo sempre na primeira vez que roda a procedure pela rotina, em verificação no banco vemos que ocorre um lock nas tabelas de inclusão (PCNFBASESAID 5:06 Row-X (SX) LOCKED Administrator CNA\KEPLER PCSIS504.EXE).
Mas quando encerramos a rotina e não tem mais nenhum lock no banco e roda a procedure novamente pela rotina, trava de novo na mesma tabela e isso fico toda vez. Até que, faz o drop na procedure, cria novamente e aí roda pela rotina que aí funciona perfeitamente.
O problema aí é que o LOCK ocorre, mas ele ocorre justamente quando roda a rotina.
Mas vou ver mais algumas coisas que vocês colocaram aqui.
Obrigado.
06/11/2015
Marcos P
LOCK é um tratamento dado apenas em tempo de SELECT... se você faz INSERT FROM SELECT, tente ajustar o nivel de isolamento para UNCOMITTED ( mesmo que seja só para teste ).
01/05/2021
Aarão Primo
pegando uma query simples rodando ela direto é extremamente rápido
porém quando coloco a mesma query para rodar por dentro de um loop ou procedure esse tempo quadriplica.
Clique aqui para fazer login e interagir na Comunidade :)