Cuando la CPU domina, la sesión de hecho trabajó en la base de datos, y lo que tiene que disminuir es el trabajo. Casi siempre el exceso viene de lectura lógica, de parse o de PL/SQL pesado.
Síntomas
En el Diagnóstico aparece el hallazgo La CPU domina el tiempo de respuesta (CPU_DOMINANTE). El texto dice cuánto del tiempo total es CPU, en porcentaje y en segundos, enumera los componentes de CPU sumados, por ejemplo CPU: FETCH dbcalls, CPU: EXEC dbcalls, sugiere empezar por las sentencias con más LIO y termina con Ver perfil por clase.
El hallazgo aparece cuando la clase CPU, la suma de la CPU de todos los tipos de llamada, concentra la mayor parte del tiempo total. La gravedad es siempre media. Con él, el hallazgo de componente dominante no se repite para la CPU.
Causa
La CPU del perfil es la CPU propia de cada llamada, como PARSE, EXEC y FETCH: su c= menos el de las llamadas hijas. Es tiempo en que la sesión se ejecutó en la CPU. Las causas más frecuentes:
- Lectura lógica en exceso (LIO). El plan lee muchos más bloques del buffer cache de lo que piden las filas devueltas: un índice poco selectivo, NESTED LOOPS sobre muchas filas, la misma tabla visitada de nuevo en cada fila. Aparece como CPU de FETCH o de EXEC.
- Parse. Hard parse por SQL sin bind, o PARSE repetido del mismo cursor. Aparece como CPU de PARSE.
- PL/SQL pesado. Lógica en bucle y funciones invocadas en cada fila de un SQL. Aparece como CPU de EXEC del bloque PL/SQL.
La cola de CPU en el servidor no entra aquí: el tiempo en que la sesión esperó una CPU libre cae en el tiempo no contabilizado dentro de las llamadas.
Solución
- Vea qué tipo de llamada pesa. En el perfil, compare
CPU: FETCH dbcalls,CPU: EXEC dbcallsyCPU: PARSE dbcalls. - Si es PARSE, siga muchos hard parses, un PARSE en cada ejecución y literales en lugar de bind.
- Si es FETCH o EXEC, busque la sentencia. En Sentencias principales por componente y por clase, abra el grupo de la clase CPU; en Sentencias SQL, compare la columna LIO con Filas.
- En el plan de la sentencia, busque en Dónde gasta el plan la operación con más LIO propio y corrija el acceso: un índice más selectivo, otro orden u otro método de join, estadísticas correctas (plan de ejecución, estimación de filas errónea).
- Si la sentencia es un bloque PL/SQL, abra SQL recursivo ejecutado por esta sentencia en su detalle. Si las hijas son pocas y baratas, la CPU es del propio código PL/SQL: para encontrar la línea que la gasta, use el profiler jerárquico de PL/SQL (
DBMS_HPROF).
Cómo confirmar
Genere un trace nuevo de la misma operación después del cambio. La Duración (s) de la clase CPU y el LIO de la sentencia corregida deben bajar, y el Tiempo total con ellos. El hallazgo desaparece cuando la CPU deja de concentrar la mayor parte del tiempo total.
Compare el tiempo total, no solo la CPU: un plan nuevo puede leer menos bloques de la caché y más del disco, y cambiar CPU por espera de lectura.
En el informe
En el informe de ejemplo, la CPU suma el 3,7% del tiempo total, sin este hallazgo. Los enlaces abren las secciones del ejemplo:
- Diagnóstico: el hallazgo y el enlace Ver perfil por clase.
- Por clase de espera, fila CPU: la suma de la CPU y, en Componentes principales, los tipos de llamada.
- Perfil, filas de CPU: una por tipo de llamada.
- Sentencias principales por clase, grupo CPU: las sentencias que más CPU gastaron.
- Sentencias SQL por contribución: columnas LIO y Filas.
- Tipos de llamada: CPU (s), Consistente (CR) y Actual (CU) de cada llamada.