Este es un error en SQL Server (de 2008 a 2014 inclusive).
Mi informe de error está aquí .
La condición de filtrado se introduce en el operador de exploración como un predicado residual, pero la memoria otorgada para la clasificación se calcula erróneamente en función de la estimación de la cardinalidad del prefiltro .
Para ilustrar el problema, podemos usar el indicador de traza 9130 (no documentado y no compatible) para evitar que el filtro sea empujado hacia el operador de exploración . La memoria otorgada a la clasificación ahora se basa correctamente en la cardinalidad estimada de la salida del filtro, no en la exploración:
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 un sistema de producción , se deberán tomar medidas para evitar la forma problemática del plan (un filtro insertado en un escaneo con una clasificación en otra columna). Una forma de hacerlo es proporcionar un índice sobre la condición del filtro y / o proporcionar el orden de clasificación requerido.
-- Index on the filter condition only
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe
ON dbo.Test (FilterMe);
Con este índice en su lugar, la concesión de memoria deseada para la clasificación es de solo 928 KB :
Yendo más lejos, el siguiente índice puede evitar la clasificación por completo ( concesión de memoria cero ):
-- Provides filtering and sort order
-- nvarchar(max) column deliberately not INCLUDEd
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe_SortMe
ON dbo.Test (FilterMe, SortMe);
Probado y con error confirmado en las siguientes compilaciones de 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)
Esto se solucionó en SQL Server 2016 Service Pack 1 . Las notas de la versión incluyen lo siguiente:
El número de error VSTS 8024987 Los
escaneos de tablas y los escaneos de índice con predicado push down tienden a sobreestimar la concesión de memoria para el operador principal.
Probado y confirmado fijo en:
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 modelos CE.