TSQL Por que o Top é mais rápido com uma variável?

10

Manhã tudo,

Eu tenho trabalhado em algum sql moderadamente complexo para 'obter' alguns dados de um banco de dados de produtos de terceiros, para exibi-los em nossos próprios aplicativos internos.

Adicionei um select para obter o registro superior de uma tabela dentro de uma subconsulta (se isso faz sentido)

a consulta levou quase 3 minutos para retornar um conjunto de resultados final de 100 registros usando

SELECT TOP 1 ...

Procurei on-line por melhorias no que estava tentando alcançar e foi sugerido que eu alterasse meu select para usar uma variável, como abaixo

DECLARE @topCount INT
SET @topCount = 1

SELECT TOP (@topCount) ...

Isso levou a mesma consulta dos 3 minutos até 1 segundo, o que é ótimo!

Mas alguém pode explicar por que isso é assim?

JamesStuddart
fonte

Respostas:

14

Quando você faz top 1o otimizador de consultas, cria um plano criado para buscar 1 linha o mais rápido possível.

Quando você usa uma variável local, o valor da variável é desconhecido para o otimizador e, em vez disso, cria um plano otimizado para buscar 100 linhas o mais rápido possível.

No seu caso, o plano de consulta gerado com uma meta de linha de 100 é o melhor plano a ser usado, mesmo quando você deseja apenas uma linha.

Para verificar, você pode tentar adicionar option (recompile)à sua consulta com a variável Nesse caso, o SQL Server usará o valor atual @topCountcomo uma meta de linha e, como esse é 1, você deve obter o plano lento.

Mikael Eriksson
fonte
Entendo a diferença de plano, mas me surpreende que buscar 1 linha possa ser mais lento do que buscar 100 linhas. Eu pensaria que, se o plano de 100 linhas funcionasse melhor, o SQL Server usaria o mesmo plano para top 1.
Brandon
@Brandon ele não busca 100 linhas, apenas cria o plano de execução com a suposição de que 100 linhas é o desejado. A execução termina quando 1 linha é encontrada.
Mikael Eriksson
Verificar o que é diferente com o plano de execução, nesses casos, provavelmente ajudaria a entender o que o problema é com top 1.
James Z