Это ошибка в SQL Server (с 2008 по 2014 год включительно).
Мой отчет об ошибках здесь .
Условие фильтрации передается в оператор сканирования как остаточный предикат, но память, предоставленная для сортировки, ошибочно рассчитывается на основе оценки количества элементов перед фильтром .
Чтобы проиллюстрировать проблему, мы можем использовать (недокументированный и неподдерживаемый) флаг трассировки 9130, чтобы не допустить попадания фильтра в оператор сканирования . Память, выделенная для сортировки, теперь корректно основывается на предполагаемой мощности вывода фильтра, а не на сканировании:
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!
Для производственной системы необходимо будет предпринять шаги, чтобы избежать проблематичной формы плана (фильтр вставляется в скан с сортировкой по другому столбцу). Один из способов сделать это - предоставить индекс условия фильтра и / или предоставить требуемый порядок сортировки.
-- Index on the filter condition only
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe
ON dbo.Test (FilterMe);
С этим индексом желаемое выделение памяти для сортировки составляет всего 928 КБ :
Если пойти дальше, следующий индекс может полностью избежать сортировки ( нулевое предоставление памяти):
-- Provides filtering and sort order
-- nvarchar(max) column deliberately not INCLUDEd
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe_SortMe
ON dbo.Test (FilterMe, SortMe);
Протестировано и исправлено на следующих сборках 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)
Это было исправлено в SQL Server 2016 с пакетом обновления 1 . Примечания к выпуску включают следующее:
Ошибка VSTS номер 8024987 Сканирование
таблиц и индекса с предикатом push down, как правило, переоценивают предоставление памяти родительскому оператору.
Проверено и подтверждено исправлено на:
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
Обе модели СЕ.