Cuando la mayor parte del tiempo es espera por la aplicación, la base de datos estaba ociosa. El camino es reducir las idas y vueltas o encontrar la demora del lado de la aplicación, no ajustar el SQL.
Síntomas
En el Diagnóstico aparece el hallazgo La sesión pasó la mayor parte del tiempo esperando a la aplicación (TEMPO_NA_APLICACAO), con el porcentaje del tiempo total al lado. El texto dice que la base de datos quedó ociosa esperando el siguiente pedido del cliente, que el ajuste de SQL no reduce ese tiempo, y termina con el enlace Ver en el perfil.
El hallazgo aparece cuando la espera SQL*Net message from client ocupa una parte grande del tiempo total. La gravedad es siempre media. Aunque esa espera sea el mayor componente del perfil, no genera también el hallazgo de componente dominante: este hallazgo ya trata ese tiempo.
Causa
SQL*Net message from client es el tiempo entre el fin de una llamada y la llegada del siguiente pedido de la aplicación. En ese intervalo la base de datos no trabaja: el tiempo es de la aplicación, de la red o del usuario. Dos formas dan el mismo hallazgo y piden soluciones diferentes:
- Muchas esperas cortas: la aplicación conversa demasiado con la base de datos. Una llamada por fila, SQL dentro de un bucle en la aplicación, una consulta por cada elemento de una lista. Cada ida y vuelta paga la latencia de la red, y el total crece con el número de llamadas.
- Pocas esperas largas: la aplicación estuvo ocupada con otra cosa entre las llamadas (procesamiento propio, llamada a otro servicio), o el usuario se detuvo. También ocurre cuando el trace se activó mucho antes de que empezara la operación o se desactivó mucho después de que terminara.
Solución
- Separe las dos formas. En la fila
SQL*Net message from clientdel perfil, compare Ocurrencias, Media (s) y Máx (s); en la distribución de latencia del evento, vea si el tiempo está en los rangos cortos o en los largos. - Si son muchas esperas cortas, reduzca las idas y vueltas: traiga las filas en lotes más grandes (muchos FETCH con pocas filas), envíe el DML en lote (array DML,
addBatchyexecuteBatchen JDBC) y cambie el bucle de consultas por una sola consulta, con join o con la lista de valores. - Si la lógica hace muchas llamadas seguidas, lleve el trabajo a la base de datos: un bloque PL/SQL o una única sentencia SQL hace en una llamada lo que el bucle de la aplicación hace en cientos.
- Con muchas esperas cortas, revise también la distancia de red: una aplicación en otro centro de datos o en otra región de la nube paga más por cada ida y vuelta.
- Si son pocas esperas largas, la demora está en la aplicación. Mida su tiempo entre las llamadas con el monitoreo de la propia aplicación: el trace de la base de datos no muestra lo que ella hacía.
- Si el Período del Resumen empieza mucho antes o termina mucho después de la operación, parte de la espera es tiempo de antes o de después de ella. Genere un trace nuevo, activado justo antes del inicio y desactivado justo después del fin.
Cómo confirmar
Después del cambio, genere un trace nuevo de la misma operación, en las mismas condiciones, y envíe el archivo nuevo. Compárelo con el informe anterior:
- el Tiempo total del Resumen bajó;
- en la fila
SQL*Net message from client, las Ocurrencias bajaron (menos idas y vueltas) o la Duración (s) bajó (menos tiempo en la aplicación); - el hallazgo desaparece cuando la espera deja de ocupar una parte grande del tiempo total.
El porcentaje puede seguir alto, y el hallazgo seguir en el Diagnóstico, si el resto del tiempo también bajó: lo que cuenta es el Tiempo total. Si la espera bajó y el tiempo total no, el tiempo cambió de componente; vuelva al perfil y ataque el mayor.
En el informe
El informe de ejemplo tiene este hallazgo, con el 71,3% del tiempo total. Los enlaces abren la parte correspondiente de él:
- Diagnóstico: el hallazgo y el enlace Ver en el perfil.
- Perfil, fila SQL*Net message from client: Ocurrencias, Media (s) y Máx (s). Haga clic en el nombre del evento para abrir la tarjeta con Normal cuando, Preocupa cuando y Dónde mirar.
- Distribución de latencia del evento: muchas esperas cortas o pocas largas.
- Sentencias principales por componente, grupo del evento: las sentencias que más esperaron a la aplicación.
- Tipos de llamada: la fila FETCH, con Cantidad y Filas.
- Resumen: Período, y Llamadas a la base de datos con las de nivel 0, que son las que pidió la aplicación.
Cada sección tiene su propia página: Perfil, Latencia, Sentencias por componente y Tipos de llamada.