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

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) 

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.


1
C'est une solution viable, jusqu'à quand (et si) ils le corrigent.
ypercubeᵀᴹ
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.