Почему отфильтрованный индекс по значению IS NULL не используется?

18

Предположим, у нас есть определение таблицы следующим образом:

CREATE TABLE MyTab (
    ID INT IDENTITY(1,1) CONSTRAINT PK_MyTab_ID PRIMARY KEY
    ,GroupByColumn NVARCHAR(10) NOT NULL
    ,WhereColumn DATETIME NULL
    )

И отфильтрованный некластеризованный индекс, подобный этому:

CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn ON MyTab 
    (GroupByColumn)
WHERE (WhereColumn IS NULL) 

Почему этот индекс не «покрывает» этот запрос:

SELECT 
    GroupByColumn
    ,COUNT(*)
FROM MyTab
WHERE WhereColumn IS NULL
GROUP BY GroupByColumn

Я получаю этот план выполнения:

введите описание изображения здесь

KeyLookup предназначен для предиката WhereColumn IS NULL.

Вот план: https://www.brentozar.com/pastetheplan/?id=SJcbLHxO7

jerik1
источник

Ответы:

23

Почему этот индекс не «покрывает» этот запрос:

Нет веских причин. Это закрывающий индекс для этого запроса.

Пожалуйста, проголосуйте за элемент обратной связи здесь: https://feedback.azure.com/forums/908035-sql-server/suggestions/32896348-filtered-index-not-used-when-is-null-and-key-looku

И как обходной путь , включают WhereColumnв отфильтрованной индекс:

CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn 
ON MyTab (GroupByColumn) include (WhereColumn)
WHERE (WhereColumn IS NULL) 
Дэвид Браун - Microsoft
источник
13
Об этом более десяти лет назад сообщила Гейл Шоу. Тогда Коннект умер. Самое близкое, что я могу найти сейчас - это feedback.azure.com/forums/908035-sql-server/suggestions/…
Пол Уайт 9
3

У меня была та же проблема, что и при тестировании несколько недель назад. У меня есть запрос с основным предикатом, который требует, чтобы возвращаемые результаты имели NULL закрытое время, и я подумал об использовании отфильтрованного индекса, так как 25K записей 2M + равны NULL, и этот показатель очень скоро уменьшится.

Отфильтрованный индекс не использовался - я предположил из-за «неуникальности» или общности - пока не нашел статью поддержки Microsoft, в которой говорится:

Чтобы решить эту проблему, включите столбец, который проверяется как NULL в возвращаемых столбцах. Или добавьте этот столбец как включающий столбцы в индексе.

Поэтому добавление столбца в указатель (или включение) представляется официальным ответом MS.

SteveO
источник
1
Это жизнеспособный обходной путь до тех пор, пока (и если) они не исправят это.
ypercubeᵀᴹ