Це помилка в 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)
Це було виправлено у пакеті оновлень 1 для SQL Server 2016 . Нотатки до випуску включають наступне:
Номер помилки VSTS 8024987
Сканування таблиць та індексів сканування з предикатом натискання вниз, як правило, завищує допуск пам'яті для батьківського оператора.
Випробувано та підтверджено зафіксовано на:
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
Обидві моделі CE.