Problema de lentidão de uma procedure

05/11/2015

23

Estou com um caso meio diferente, não sei se alguém já passou por isso.

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.
Responder

Post mais votado

05/11/2015

Eduardo,

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 !
Responder

Mais Posts

Só mais um detalhe, quando rodo a procedure diretamente pelo banco de dados (PL/SQL), a procedure roda sem nenhum problema. Só pelo aplicativo Delphi que ocorre esse problema, mas se dropar e criar antes de executar o aplicativo, também fica rápido.
Responder
Boa tarde Eduardo

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
Responder
Fernando,

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.
Responder
Dá a impressão que ocorre um problema com a procedure no banco de dados, aí quando dropo e crio novamente, restaura a procedure, aí executa normalmente.
Responder
Eduardo

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.
Responder
Fernando e Marcos:

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.
Responder

06/11/2015

Marcos P

O LOCK ocorre em tempo de insert ?

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 ).
Responder

01/05/2021

Aarão Primo

Estou com o mesmo problema no oracle 19c,
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.
Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários. Para saber mais sobre o uso de cookies,
consulte nossa política de privacidade. Ao continuar navegando em nosso site, você concorda com a nossa política.

Aceitar