Este é um erro no SQL Server (de 2008 a 2014, inclusive).
Meu relatório de bug está aqui .
A condição de filtragem é inserida no operador de varredura como um predicado residual, mas a memória concedida para a classificação é calculada erroneamente com base na estimativa de cardinalidade de pré-filtro .
Para ilustrar o problema, podemos usar o sinalizador de rastreamento 9130 (não documentado e não suportado) para impedir que o Filtro seja empurrado para baixo no operador de digitalização . A memória concedida à classificação agora está corretamente baseada na cardinalidade estimada da saída do filtro, não na verificação:
SELECT
T.TID,
T.FilterMe,
T.SortMe,
T.Unused
FROM dbo.Test AS T
WHERE
T.FilterMe = 567
ORDER BY
T.SortMe
OPTION (QUERYTRACEON 9130); -- Not for production systems!
Para um sistema de produção , serão necessárias etapas para evitar a forma problemática do plano (um filtro inserido em uma varredura com uma classificação em outra coluna). Uma maneira de fazer isso é fornecer um índice na condição do filtro e / ou fornecer a ordem de classificação necessária.
-- Index on the filter condition only
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe
ON dbo.Test (FilterMe);
Com esse índice, a concessão de memória desejada para a classificação é de apenas 928 KB :
Indo além, o seguinte índice pode evitar a classificação completamente ( concessão de memória zero ):
-- Provides filtering and sort order
-- nvarchar(max) column deliberately not INCLUDEd
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe_SortMe
ON dbo.Test (FilterMe, SortMe);
Testado e bug confirmado nas seguintes compilações do SQL Server x64 Developer Edition:
2014 : 12.00.2430 (RTM CU4)
2012 : 11.00.5556 (SP2 CU3)
2008R2 : 10.50.6000 (SP3)
2008 : 10.00.6000 (SP4)
Isso foi corrigido no SQL Server 2016 Service Pack 1 . As notas de versão incluem o seguinte:
Número de bug do VSTS 8024987 As
varreduras de tabela e de índice com predicado push down tendem a superestimar a concessão de memória para o operador pai.
Testado e confirmado corrigido em:
Microsoft SQL Server 2016 (SP1) - 13.0.4001.0 (X64) Developer Edition
Microsoft SQL Server 2014 (SP2-CU3) 12.0.5538.0 (X64) Developer Edition
Ambos os modelos CE.