Por onde começar
Quando o sistema fica lento e a culpa cai no banco, o instinto é sair executando queries aleatórias em V$SESSION. Isso raramente funciona. Existe uma ordem lógica.
1. Confirmar que o problema é no banco
Antes de qualquer coisa: o gargalo é no banco ou na aplicação?
Verifico o tempo de resposta ponta a ponta com APM ou logs da aplicação. Se a query demora 50ms no banco mas a request leva 3s, o problema está em outro lugar.
2. AWR: visão macro
O AWR (Automatic Workload Repository) é o ponto de partida para análise histórica.
-- Listar snapshots disponíveis
SELECT snap_id, begin_interval_time, end_interval_time
FROM dba_hist_snapshot
ORDER BY snap_id DESC
FETCH FIRST 20 ROWS ONLY;
Gero o relatório HTML entre dois snapshots do período problemático e foco em:
- Top 5 Timed Events — onde o banco passou o tempo
- Top SQL by Elapsed Time — SQLs mais caros
- Instance Efficiency — buffer cache hit, redo log contention
3. ASH: visão em tempo real
O ASH (Active Session History) é fundamental para problemas que estão acontecendo agora:
-- Sessions com mais wait nos últimos 5 minutos
SELECT sql_id, event, COUNT(*) AS amostras
FROM v$active_session_history
WHERE sample_time > SYSDATE - 5/1440
GROUP BY sql_id, event
ORDER BY amostras DESC
FETCH FIRST 10 ROWS ONLY;
4. Identificar o SQL problemático
Com o sql_id em mãos:
-- Ver o texto completo
SELECT sql_fulltext
FROM v$sql
WHERE sql_id = '&sql_id';
-- Ver plano de execução atual
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id', NULL, 'ALLSTATS LAST'));
Os sinais de alerta no plano:
FULL TABLE SCANem tabelas grandes sem filtro seletivoNESTED LOOPScomBUFFER SORTem volumes altos- Estimativas de cardinalidade muito distantes da realidade (sinal de estatísticas desatualizadas)
5. Estatísticas
Estatísticas desatualizadas são causa frequente de planos ruins:
-- Verificar quando foram coletadas pela última vez
SELECT table_name, last_analyzed, num_rows
FROM dba_tables
WHERE owner = 'MEU_SCHEMA'
ORDER BY last_analyzed ASC NULLS FIRST;
Se uma tabela de milhões de linhas não tem estatísticas há semanas, coleta imediata:
EXEC DBMS_STATS.GATHER_TABLE_STATS('MEU_SCHEMA', 'MINHA_TABELA', cascade => TRUE);
Conclusão
A ordem importa: confirmar o problema → AWR para contexto histórico → ASH para tempo real → SQL problemático → plano de execução → estatísticas. Pular etapas gera diagnósticos errados e soluções que não resolvem nada.