Eu tenho uma consulta que une algumas tabelas e executa muito mal - as estimativas de linha estão muito distantes (1000 vezes) e a junção Nested Loops é escolhida, resultando em várias varreduras de tabela. A forma da consulta é bastante direta, parecida com esta:
SELECT t1.id
FROM t1
INNER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id
LEFT OUTER JOIN t4 ON t3.t4_id = t4.id
WHERE t4.id = some_GUID
Brincando com a consulta, notei que, quando sugiro que ela use uma junção de mesclagem para uma das junções, ela é executada muitas vezes mais rapidamente. Isso eu entendo - a junção de mesclagem é uma opção melhor para os dados que ingressam, mas o SQL Server simplesmente não calcula corretamente a escolha dos Loops Aninhados.
O que não entendo completamente é por que essa dica de associação altera todas as estimativas para todos os operadores do plano? Ao ler diferentes artigos e livros, presumi que as estimativas de cardinalidade são executadas antes da construção do plano; portanto, o uso de uma dica não alteraria as estimativas, mas instruiria explicitamente o SQL Server a usar uma implementação de junção física específica.
O que vejo, no entanto, é que a dica Mesclar faz com que todas as estimativas se tornem perfeitas. Por que isso acontece e existem técnicas comuns para fazer com que o otimizador de consultas faça uma estimativa melhor sem uma dica - considerando que as estatísticas obviamente permitem isso?
UPD: planos de execução anonimizados podem ser encontrados aqui: https://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl=0 https://www.dropbox.com/s/38sjtv0t7vjjfdp/no_hints_join.sqlplan?dl = 0
Eu verifiquei as estatísticas usadas pelas duas consultas usando TF 3604, 9292 e 9204, e essas são idênticas. No entanto, os índices examinados / pesquisados diferem entre as consultas.
Além disso, tentei executar a consulta OPTION (FORCE ORDER)
- ela é executada ainda mais rápido do que a junção de mesclagem, escolhendo HASH MATCH para cada junção.