01
O plano não é da consulta, é do momento em que ela foi planejada
A intuição de quem escreve SQL é que a consulta descreve o resultado e o banco descreve o caminho, e essa parte está certa. O que quase sempre falta é o passo seguinte: o caminho é escolhido por um otimizador baseado em custo, que estima quantas linhas cada operação vai devolver e escolhe o plano mais barato segundo essa estimativa. A estimativa não é uma medição, é uma projeção feita a partir de estatísticas amostradas em algum momento do passado. Nada disso é estável, e nenhuma parte disso está no seu código.
A consequência é que a mesma consulta pode ter planos diferentes em dias diferentes sem que uma linha tenha mudado. Isso não é um defeito do banco, é o comportamento desejado: se a tabela cresceu de dez mil para dez milhões de linhas, o plano correto mudou de verdade, e um otimizador que insistisse no plano antigo seria pior. O problema aparece quando a estimativa está errada, porque aí o otimizador escolhe corretamente segundo uma realidade que não existe.
A pergunta útil quando uma consulta degrada sem alteração de código não é o que mudou no código, é qual das entradas do otimizador mudou. Existem quatro, e cada uma tem um sintoma e um teste próprios.
| Entrada do otimizador | O que muda sozinho | Sintoma típico | Como confirmar |
|---|---|---|---|
| Estatísticas de distribuição | Envelhecem conforme a tabela cresce ou muda de perfil | Estimativa de linhas ordens de grandeza abaixo do real | Comparar linhas estimadas com linhas retornadas no plano executado |
| Parâmetro capturado no primeiro planejamento | Depende de qual valor chegou primeiro após reinício ou invalidação | Consulta rápida para um cliente e lenta para outro, mesmo SQL | Executar com valor literal e comparar com a versão parametrizada |
| Volume e seletividade real dos dados | Cresce com o negócio, muda com sazonalidade | Degradação gradual que vira degrau ao cruzar um limiar | Histórico de tempo médio contra histórico de contagem de linhas |
| Correlação entre colunas do filtro | Aparece quando dados novos criam dependência entre campos | Estimativa erra por multiplicação de seletividades independentes | Contar linhas do filtro combinado e comparar com o produto das partes |
As duas linhas que mais enganam são a terceira e a quarta. A degradação por volume parece contínua, mas na prática é um degrau: enquanto o custo estimado da varredura sequencial for maior que o do índice, nada acontece, e no dia em que a tabela cruza o ponto de empate o plano vira de uma execução para a outra. A correlação entre colunas é ainda mais silenciosa, porque o otimizador supõe independência por padrão. Se você filtra por cidade e por estado, ele multiplica as duas seletividades como se fossem eventos independentes e estima cem vezes menos linhas do que existem, quando na verdade cidade determina estado.