Plan de consulta degradado (lentitud repentina)
Una consulta que ayer era rápida hoy es de repente lenta. Normalmente el optimizador ha cambiado a un plan peor. Buscamos la causa raíz entre estadísticas desactualizadas, sensibilidad a parámetros, crecimiento del volumen de datos o un cambio repentino de plan, y estabilizamos el plan.
¿El plan cambió realmente, y cuándo?
¿Hay varios planes (plan_hash/plan_generation) para la misma consulta, y cuándo empezó la lentitud? ¿Coincide con un despliegue reciente, una actualización, un cambio de parámetros o una carga de datos grande?
SELECT sql_id, plan_hash_value, executions, ROUND(elapsed_time/GREATEST(executions,1)/1e6,3) AS sec_per_exec, first_load_time
FROM v$sql WHERE sql_id='&sqlid' ORDER BY first_load_time;- Las estadísticas pueden estar desactualizadas
- La misma consulta se comporta de forma distinta según el parámetro (sniffing/peeking)
- El volumen de datos ha crecido considerablemente
- El plan cambió de repente tras una actualización/flush
¿Están actualizadas las estadísticas?
El optimizador basa sus decisiones en las estadísticas. Si la fecha del último analyze es antigua o el contador de modificaciones es alto, las estimaciones pueden haberse desviado realmente, lo que lleva a un plan malo.
SELECT table_name, num_rows, last_analyzed, stale_stats
FROM dba_tab_statistics WHERE table_name='T';- Las estadísticas están desactualizadas/faltan
- Las estadísticas están actualizadas, pero el plan sigue siendo sensible a parámetros
¿Hay sensibilidad a parámetros?
La consulta elige y almacena en caché un plan según el valor del parámetro de su primera ejecución (MSSQL parameter sniffing / Oracle bind peeking). Ese plan puede ser malo para otros valores con una distribución sesgada.
SELECT sql_id, child_number, plan_hash_value, is_bind_sensitive, is_bind_aware
FROM v$sql WHERE sql_id='&sqlid';- Sí, el plan alterna entre bueno y malo según el parámetro
- Se conoce el plan correcto; quiero fijarlo de forma permanente
Causa raíz: estadísticas desactualizadas / ausentes
Basándose en estadísticas antiguas que no se corresponden con la realidad, el optimizador estimó mal el número de filas y eligió un plan malo. Es la causa más común de degradación de planes.
Causa raíz: sensibilidad a parámetros (sniffing / bind peeking)
El plan en caché se eligió para el primer valor de parámetro que llegó y es malo para otros valores con una distribución sesgada. El objetivo es asegurarse de que se elige un plan adecuado al valor.
Solución: fijar el plan correcto (baseline / force plan)
Si existe un plan bueno conocido, fijarlo para que el optimizador no se desvíe de él detiene la degradación de forma permanente.
Causa raíz: el volumen de datos creció y el plan ya no es adecuado
A medida que crece la tabla, un plan que antes era ideal (p. ej. nested loop) ahora escala mal; el optimizador necesita estadísticas y rutas de acceso que reflejen correctamente el crecimiento.
Causa raíz: cambio repentino de plan (actualización / vaciado de caché)
El plan cambió de repente tras una actualización de versión, un cambio de parámetros o el vaciado de la caché de planes. El comportamiento del optimizador o las condiciones del entorno han cambiado.