Pourquoi l'index filtré sur la valeur IS NULL n'est pas utilisé?

18

Supposons que nous ayons une définition de table comme celle-ci:

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

Et un index non cluster filtré comme celui-ci:

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

Pourquoi cet index ne "couvre" pas cette requête:

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

Je reçois ce plan d'exécution:

entrez la description de l'image ici

Le KeyLookup est pour le prédicat WhereColumn IS NULL.

Voici le plan: https://www.brentozar.com/pastetheplan/?id=SJcbLHxO7

jerik1
la source

Réponses:

23

Pourquoi cet index ne "couvre" pas cette requête:

Aucune bonne raison. Il s'agit d'un index de couverture pour cette requête.

Veuillez voter pour l'article de retour ici: https://feedback.azure.com/forums/908035-sql-server/suggestions/32896348-filtered-index-not-used-when-is-null-and-key-looku

Et comme solution de contournement, incluez le WhereColumndans l'index filtré:

CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn 
ON MyTab (GroupByColumn) include (WhereColumn)
WHERE (WhereColumn IS NULL) 
David Browne - Microsoft
la source
13
Cela a été rapporté il y a plus d'une décennie par Gail Shaw. Puis Connect est mort. Le plus proche que je peux trouver maintenant est feedback.azure.com/forums/908035-sql-server/suggestions/…
Paul White 9
3

J'ai eu le même problème, je pense, lors de tests il y a des semaines. J'ai une requête avec un prédicat principal qui nécessite que les résultats retournés aient une heure fermée NULL et j'ai pensé à utiliser un index filtré car 25K d'enregistrements 2M + sont NULL et ce chiffre diminuera très bientôt.

L'index filtré n'a pas été utilisé - j'ai supposé en raison de la `` non-unicité '' ou des points communs - jusqu'à ce que je trouve un article de support Microsoft qui dit:

Pour résoudre ce problème, incluez la colonne testée comme NULL dans les colonnes renvoyées. Ou, ajoutez cette colonne en tant que colonnes d'inclusion dans l'index.

L'ajout de la colonne à l'index (ou à l'inclusion) semble donc être la réponse officielle des États membres.

SteveO
la source
1
C'est une solution viable, jusqu'à quand (et si) ils le corrigent.
ypercubeᵀᴹ