Quando a maior parte do tempo é espera pela aplicação, o banco estava ocioso. O caminho é reduzir as idas e voltas ou achar a demora do lado da aplicação, não ajustar SQL.
Sintomas
No Diagnóstico, aparece o achado A sessão passou a maior parte do tempo esperando a aplicação (TEMPO_NA_APLICACAO), com o percentual do tempo total ao lado. O texto diz que o banco ficou ocioso esperando o próximo pedido do cliente, que ajuste de SQL não reduz esse tempo, e termina com o link Ver no perfil.
O achado aparece quando a espera SQL*Net message from client ocupa uma parte grande do tempo total. A severidade é sempre média. Mesmo quando essa espera é o maior componente do perfil, ela não gera também o achado de componente dominante: este achado já trata desse tempo.
Causa
SQL*Net message from client é o tempo entre o fim de uma chamada e a chegada do próximo pedido da aplicação. Nesse intervalo o banco não trabalha: o tempo é da aplicação, da rede ou do usuário. Duas formas dão o mesmo achado e pedem soluções diferentes:
- Muitas esperas curtas: a aplicação conversa demais com o banco. Uma chamada por linha, SQL dentro de laço na aplicação, uma consulta por item de uma lista. Cada ida e volta paga a latência da rede, e o total cresce com o número de chamadas.
- Poucas esperas longas: a aplicação ficou ocupada com outra coisa entre as chamadas (processamento próprio, chamada a outro serviço), ou o usuário parou. Também acontece quando o trace foi ligado bem antes de a operação começar ou desligado bem depois do fim.
Resolução
- Separe as duas formas. Na linha
SQL*Net message from clientdo perfil, compare Ocorrências, Média (s) e Máx (s); na distribuição de latência do evento, veja se o tempo está nas faixas curtas ou nas longas. - Se são muitas esperas curtas, reduza as idas e voltas: traga as linhas em lotes maiores (muitos FETCH com poucas linhas), mande DML em lote (array DML,
addBatcheexecuteBatchno JDBC) e troque o laço de consultas por uma consulta só, com junção ou com a lista de valores. - Se a lógica faz muitas chamadas em sequência, leve o trabalho para o banco: um bloco PL/SQL ou um único SQL faz numa chamada o que o laço da aplicação faz em centenas.
- Com muitas esperas curtas, confira também a distância de rede: aplicação em outro datacenter ou em outra região da nuvem paga mais por ida e volta.
- Se são poucas esperas longas, a demora está na aplicação. Meça o tempo dela entre as chamadas com a monitoração da própria aplicação: o trace do banco não mostra o que ela fazia.
- Se o Período do Resumo começa bem antes ou termina bem depois da operação, parte da espera é tempo de antes ou de depois dela. Gere um trace novo, ligado logo antes do início e desligado logo depois do fim.
Como confirmar
Depois da mudança, gere um trace novo da mesma operação, nas mesmas condições, e envie o arquivo novo. Compare com o relatório anterior:
- o Tempo total do Resumo caiu;
- na linha
SQL*Net message from client, as Ocorrências caíram (menos idas e voltas) ou a Duração (s) caiu (menos tempo na aplicação); - o achado some quando a espera deixa de ocupar uma parte grande do tempo total.
O percentual pode continuar alto, e o achado continuar no Diagnóstico, se o resto do tempo também caiu: o que vale é o Tempo total. Se a espera caiu e o tempo total não, o tempo mudou de componente; volte ao perfil e ataque o maior.
No relatório
O relatório de exemplo tem este achado, com 71,3% do tempo total. Os links abrem a parte correspondente dele:
- Diagnóstico: o achado e o link Ver no perfil.
- Perfil, linha SQL*Net message from client: Ocorrências, Média (s) e Máx (s). Clique no nome do evento para abrir o cartão com Normal quando, Preocupa quando e Onde olhar.
- Distribuição de latência do evento: muitas esperas curtas ou poucas longas.
- Principais comandos por componente, grupo do evento: os comandos que mais esperaram a aplicação.
- Tipos de chamada: a linha FETCH, com Quantidade e Linhas.
- Resumo: Período, e Chamadas ao banco com as de nível 0, que são as que a aplicação pediu.
Cada seção tem a própria página: Perfil, Latência, Comandos por componente e Tipos de chamada.