Plano de execução regrediu (lentidão repentina)
Uma consulta que ontem era rápida está de repente lenta hoje. Geralmente o otimizador mudou para um plano pior. Encontramos a causa raiz entre estatísticas desatualizadas, sensibilidade a parâmetros, crescimento do volume de dados ou uma mudança repentina de plano, e estabilizamos o plano.
O plano realmente mudou, e quando?
Há vários planos (plan_hash/plan_generation) para a mesma consulta, e quando a lentidão começou? Coincide com um deploy, upgrade, mudança de parâmetro ou carga grande de dados recente?
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;- As estatísticas podem estar desatualizadas
- A mesma consulta se comporta de forma diferente conforme o parâmetro (sniffing/peeking)
- O volume de dados cresceu significativamente
- O plano mudou de repente após um upgrade/flush
As estatísticas estão atualizadas?
O otimizador baseia suas decisões nas estatísticas. Se a data do último analyze for antiga ou o contador de modificações estiver alto, as estimativas podem ter de fato se desviado, o que leva a um plano ruim.
SELECT table_name, num_rows, last_analyzed, stale_stats
FROM dba_tab_statistics WHERE table_name='T';- As estatísticas estão desatualizadas/ausentes
- As estatísticas estão atualizadas, mas o plano continua sensível a parâmetros
Há sensibilidade a parâmetros?
A consulta escolhe e coloca em cache um plano com base no valor do parâmetro da sua primeira execução (parameter sniffing no MSSQL / bind peeking no Oracle). Esse plano pode ser ruim para outros valores com distribuição desigual.
SELECT sql_id, child_number, plan_hash_value, is_bind_sensitive, is_bind_aware
FROM v$sql WHERE sql_id='&sqlid';- Sim, o plano alterna entre bom e ruim conforme o parâmetro
- O plano correto é conhecido, quero fixá-lo de forma permanente
Causa raiz: estatísticas desatualizadas / ausentes
Com base em estatísticas antigas que não correspondem à realidade, o otimizador estimou errado o número de linhas e escolheu um plano ruim. Esta é a causa mais comum de regressão de plano.
Causa raiz: sensibilidade a parâmetros (sniffing / bind peeking)
O plano em cache foi escolhido para o primeiro valor de parâmetro que chegou e é ruim para outros valores com distribuição desigual. O objetivo é garantir que seja escolhido um plano adequado ao valor.
Solução: fixe o plano correto (baseline / force plan)
Se existir um plano bom conhecido, fixá-lo para que o otimizador não se desvie dele interrompe a regressão de forma permanente.
Causa raiz: o volume de dados cresceu e o plano não serve mais
À medida que a tabela cresce, um plano que antes era ideal (ex.: nested loop) passa a escalar mal; o otimizador precisa de estatísticas e caminhos de acesso que reflitam corretamente o crescimento.
Causa raiz: mudança repentina de plano (upgrade / flush do cache)
O plano mudou de repente após um upgrade de versão, uma mudança de parâmetro ou o esvaziamento do plan cache. O comportamento do otimizador ou as condições do ambiente mudaram.