Por que o índice filtrado no valor IS NULL não é usado?

18

Suponha que temos uma definição de tabela como esta:

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

E um índice não agrupado e filtrado como este:

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

Por que esse índice não está "cobrindo" esta consulta:

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

Estou recebendo este plano de execução:

insira a descrição da imagem aqui

O KeyLookup é para o predicado WhereColumn IS NULL.

Aqui está o plano: https://www.brentozar.com/pastetheplan/?id=SJcbLHxO7

jerik1
fonte

Respostas:

23

Por que esse índice não está "cobrindo" esta consulta:

Não há uma boa razão. Esse é um índice de cobertura para essa consulta.

Vote aqui no item feeback: https://feedback.azure.com/forums/908035-sql-server/suggestions/32896348-filtered-index-not-used-when-is-null-and-key-looku

Como alternativa, inclua o WhereColumníndice filtrado:

CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn 
ON MyTab (GroupByColumn) include (WhereColumn)
WHERE (WhereColumn IS NULL) 
David Browne - Microsoft
fonte
13
Isso foi relatado há mais de uma década por Gail Shaw. Então o Connect morreu. O mais próximo que posso encontrar agora é feedback.azure.com/forums/908035-sql-server/suggestions/…
Paul White 9
3

Eu tive o mesmo problema que penso ao fazer alguns testes semanas atrás. Eu tenho uma consulta com um predicado primário que exige que os resultados retornados tenham um NULL fechado no tempo e pensei em usar um índice filtrado, pois 25K de 2M + registros são NULL e esse número diminuirá muito em breve.

O índice filtrado não foi usado - presumi que devido a 'não exclusividade' ou semelhança - até encontrar um artigo de suporte da Microsoft que diz:

Para resolver esse problema, inclua a coluna que é testada como NULL nas colunas retornadas. Ou adicione esta coluna como incluir colunas no índice.

Portanto, adicionar a coluna ao Índice (ou Incluir) parece ser a resposta oficial do MS.

SteveO
fonte
1
É uma solução viável, até quando (e se) eles o corrigirem.
precisa saber é o seguinte