Eu imaginaria que, quando uma consulta incluir TOP n, o mecanismo de banco de dados executaria a consulta ignorando a cláusula TOP e, no final, reduziria apenas o resultado definido para o número n de linhas solicitadas. O plano gráfico de execução parece indicar que este é o caso - TOP é o "último" passo. Mas parece que há mais coisas acontecendo.
A maneira como o texto acima é formulado me faz pensar que você pode ter uma imagem mental incorreta de como uma consulta é executada. Um operador em um plano de consulta não é uma etapa (onde o conjunto de resultados completo de uma etapa anterior é avaliado pela próxima.
O SQL Server usa um modelo de execução em pipeline , em que cada operador expõe métodos como Init () , GetRow () e Close () . Como o nome GetRow () sugere, um operador produz uma linha por vez, sob demanda (conforme exigido pelo operador pai). Isso está documentado na referência de Operadores lógicos e físicos dos Manuais Online , com mais detalhes em minha postagem no blog Por que os planos de consulta são executados para trás . Esse modelo de linha por vez é essencial para formar uma intuição sólida para a execução de consultas.
Minha pergunta é: como (e por que) uma TOP
cláusula n afeta o plano de execução de uma consulta?
Algumas operações lógicas como TOP
semi-junções e a FAST n
dica de consulta afetam a maneira como o otimizador de consulta custa alternativas ao plano de execução. A idéia básica é que uma possível forma de plano possa retornar as primeiras n linhas mais rapidamente do que um plano diferente que foi otimizado para retornar todas as linhas.
Por exemplo, a junção de loops aninhados indexados geralmente é a maneira mais rápida de retornar um pequeno número de linhas, embora a junção de hash ou mesclagem com varreduras possa ser mais eficiente em conjuntos maiores. A maneira como o otimizador de consulta raciocina sobre essas opções é definindo uma meta de linha em um ponto específico na árvore lógica de operações.
Uma meta de linha modifica a maneira como as alternativas do plano de consulta são avaliadas. A essência disso é que o otimizador começa com o custo de cada operador como se o conjunto de resultados completo fosse necessário, define uma meta de linha no ponto apropriado e depois trabalha de volta na árvore do plano, estimando o número de linhas que ele espera examinar para atingir a meta da linha.
Por exemplo, uma lógica TOP(10)
define uma meta de linha 10 em um ponto específico da árvore de consultas lógicas. Os custos dos operadores que antecedem o objetivo da linha são modificados para estimar quantas linhas eles precisam produzir para atingir o objetivo da linha. Esse cálculo pode se tornar complexo, portanto, é mais fácil entender tudo isso com um exemplo completo e planos de execução anotados. As metas de linha podem afetar mais do que a escolha do tipo de junção ou se as buscas e pesquisas são preferidas às verificações. Mais detalhes sobre isso aqui .
Como sempre, um plano de execução selecionado com base em uma meta de linha está sujeito às habilidades de raciocínio do otimizador e à qualidade das informações fornecidas a ele. Nem todo plano com uma meta de linha produzirá o número necessário de linhas mais rapidamente na prática, mas de acordo com o modelo de custo que produzirá.
Nos casos em que um plano de meta de linha não é mais rápido, geralmente há maneiras de modificar a consulta ou fornecer melhores informações ao otimizador, de modo que o plano naturalmente selecionado seja o melhor. Qual opção é apropriada no seu caso depende dos detalhes do curso. O recurso de meta de linha geralmente é muito eficaz (embora exista um bug a ser observado quando usado em planos de execução paralelos).
Sua consulta e plano específicos podem não ser adequados para uma análise detalhada aqui (por todos os meios, forneça um plano de execução real, se você desejar), mas espero que as idéias descritas aqui permitam que você avance.
ORDER BY
cláusula AdicionandoTOP
alterações onde esse tipo de plano ocorre, mas estou mais preocupado com a forma como isso afeta o número de execuções de buscas de índice na tabela B ... (é claro que as duas podem estar relacionadas - não sei)