Como eu anulo (sobrescrevo) a escolha de índice do otimizador no MS SQL Server?
Use uma dica de índice (index hint) na cláusula FROM, com a sintaxe atual WITH (INDEX (...)). Isso força o otimizador de consultas a usar (ou ignorar) um índice específico, em vez de deixar ele decidir sozinho.
Forçar o uso de um índice específico:
SELECT *
FROM MinhaTabela WITH (INDEX(IX_MinhaTabela_Coluna))
WHERE Coluna = 'valor'
Também é possível referenciar o índice pelo seu ID numérico, mas usar o nome é mais seguro e recomendado, pois o ID pode mudar se os índices forem recriados.
Forçar uma varredura completa da tabela (ignorando todos os índices):
SELECT *
FROM MinhaTabela WITH (INDEX(0))
WHERE Coluna = 'valor'
Forçar o uso do índice clustered:
SELECT *
FROM MinhaTabela WITH (INDEX(1))
WHERE Coluna = 'valor'
(INDEX(1) sempre aponta para o índice clustered, quando ele existe.)
Importante: o uso de index hints deve ser feito com cautela. Na maioria dos casos, o otimizador do SQL Server já escolhe o melhor plano de execução. Forçar um índice manualmente pode:
- Prejudicar a performance se os dados ou estatísticas mudarem com o tempo;
- Impedir que o SQL Server se beneficie de melhorias automáticas do otimizador em versões futuras;
- Mascarar problemas reais, como estatísticas desatualizadas (o correto nesse caso costuma ser rodar
UPDATE STATISTICSem vez de forçar um índice).
Uma alternativa mais suave, quando o problema é instabilidade no plano de execução, é usar OPTION (RECOMPILE) ou hints de nível de consulta como OPTION (FORCESEEK), que orientam o otimizador sem removerem totalmente sua liberdade de decisão.