Pular para o conteúdo
WaitScope Entrar Solicitar acesso (por e-mail) Menu

Um PARSE a cada execução

O achado PARSE_POR_EXECUCAO aparece quando um comando muito executado faz um PARSE a cada execução. Manter o cursor aberto evita o PARSE repetido.

Vale para: Traces 10046, com ou sem esperas

Um PARSE para cada execução quer dizer que o cursor é aberto e fechado a cada uso. Mesmo leve, cada parse custa uma chamada, CPU e disputa na library cache; o SQL preparado uma vez e executado muitas evita tudo isso.

Sintomas

No Diagnóstico, aparece o achado Comando #n: um PARSE a cada execução (n PARSE, n EXEC) (PARSE_POR_EXECUCAO), por exemplo Comando #1: um PARSE a cada execução (2.000 PARSE, 2.000 EXEC). O texto diz que o cursor é aberto e fechado a cada uso e termina com Ver comando #1, que abre o detalhe do comando.

O achado aparece para os comandos muito executados em que quase toda execução (EXEC) vem com um PARSE próprio, a começar pelos que mais pesam. A severidade é baixa e passa a média quando o PARSE do comando pesa mais no tempo total; esse peso é o percentual ao lado do título.

Numa linha com o selo N variantes, que soma SQL só com literais diferentes, o PARSE com hard parse é o de cada valor novo, e quem trata dele é o achado de literais em vez de bind. Este achado só aparece nessa linha quando as variantes se repetem e o PARSE delas é quase todo leve: o cursor de cada variante é aberto e fechado a cada uso.

Causa

A aplicação prepara o SQL, executa uma vez e fecha o cursor, e repete o ciclo na próxima execução. Cada ciclo custa uma chamada PARSE a mais e pode custar uma ida e volta a mais na rede. Mesmo quando o parse é leve (soft parse, sem mis=1), ele gasta CPU e disputa a library cache com as outras sessões.

É comum em código que cria o statement dentro do laço, em drivers sem cache de statements e em camadas de acesso que abrem e fecham o cursor a cada chamada.

Resolução

  1. Na aplicação, prepare o SQL uma vez e execute muitas: guarde o statement preparado e reutilize, em vez de criar e fechar a cada execução.
  2. Ligue o cache de statements do driver, que mantém os cursores abertos entre usos. No JDBC da Oracle, por exemplo:
    OracleConnection oconn = conn.unwrap(OracleConnection.class);
    oconn.setImplicitCachingEnabled(true);
    oconn.setStatementCacheSize(50);
  3. Confira o session_cached_cursors. No PL/SQL, ele define quantos cursores o PL/SQL mantém abertos, e o PARSE repetido some. Na aplicação cliente, ele deixa cada PARSE mais barato, mas a chamada continua no trace: o que a tira são os passos 1 e 2.
    select value from v$parameter where name = 'session_cached_cursors';
  4. Se o comando é SQL dinâmico montado com os valores no texto, o problema é outro: veja literais em vez de bind.

Como confirmar

Gere um trace novo da mesma operação depois da mudança e abra o detalhe do comando. Na tabela Chamadas, a Quantidade de PARSE deve ficar muito abaixo da de EXEC, e o achado some.

No perfil, CPU: PARSE dbcalls deve cair. Com o cache de statements na aplicação, as Ocorrências de SQL*Net message from client também podem cair.

No relatório

No relatório de exemplo, o comando #1 tem 1 PARSE e 1 EXEC: um PARSE por execução, mas numa execução só, sem achado. O relatório do caso 1, de um trace real, tem este achado (Diagnóstico do caso 1). Os links abaixo abrem as seções do exemplo:

Esperas como library cache: mutex X e cursor: pin S, da classe Concurrency, também acompanham PARSE em excesso: veja disputa por estruturas internas. O detalhe do comando tem página própria: detalhe do comando.

Atualizado em 29/10/2026. Relatar erro nesta página