Digamos que eu tenha os seguintes valores inteiros em uma tabela
32
11
15
123
55
54
23
43
44
44
56
23
OK, a lista pode continuar; Não importa. Agora eu quero consultar esta tabela e quero retornar um certo número de arquivos closest records
. Digamos que eu queira retornar 10 correspondências de registro mais próximas ao número 32. Posso fazer isso com eficiência?
Está no SQL Server 2014.
Supondo que a coluna esteja indexada, o seguinte deve ser razoavelmente eficiente.
Com duas buscas de 10 linhas e depois uma espécie de (até) 20 retornadas.
(ou seja, potencialmente algo como o abaixo)
Ou outra possibilidade (que reduz o número de linhas classificadas para no máximo 10)
NB: O plano de execução acima foi para a definição de tabela simples
Tecnicamente, o Sort na ramificação inferior também não deve ser necessário, pois também é ordenado por Diff, e seria possível mesclar os dois resultados ordenados. Mas não consegui esse plano.
A query tem
ORDER BY Diff ASC, YourCol ASC
e não apenasORDER BY YourCol ASC
, pois foi isso que acabou dando certo para se livrar do Sort no branch superior do plano. Eu precisava adicionar a coluna secundária (mesmo que ela nunca mude o resultado, poisYourCol
será o mesmo para todos os valores com o mesmo Diff) para que ela passe pela junção de mesclagem (concatenação) sem adicionar um Sort.O SQL Server parece capaz de inferir que um índice em X procurado em ordem crescente entregará linhas ordenadas por X + Y e nenhuma classificação é necessária. Mas não é capaz de inferir que percorrer o índice em ordem decrescente entregará linhas na mesma ordem que YX (ou mesmo apenas unário menos X). Ambas as ramificações do plano usam um índice para evitar uma classificação, mas as
TOP 10
da ramificação inferior são classificadas porDiff
(mesmo que já estejam nessa ordem) para colocá-las na ordem desejada para a mesclagem.Para outras definições de consultas/tabelas, pode ser mais complicado ou não ser possível obter o plano de mesclagem com apenas uma espécie de uma ramificação - pois depende de encontrar uma expressão de ordenação que o SQL Server:
TOP
Estou um pouco intrigado e surpreso que tenhamos que fazer União neste caso. A seguir é simples e mais eficiente
A seguir está o código completo e o plano de execução comparando as duas consultas
Refinamento da segunda sugestão de Martin: