Warum wird der gefilterte Index für den IS NULL-Wert nicht verwendet?

18

Angenommen, wir haben eine Tabellendefinition wie diese:

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

Und ein gefilterter nicht gruppierter Index wie dieser:

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

Warum dieser Index diese Abfrage nicht "abdeckt":

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

Ich erhalte diesen Ausführungsplan:

Bildbeschreibung hier eingeben

Das KeyLookup ist für das Vergleichselement WhereColumn IS NULL.

Hier ist der Plan: https://www.brentozar.com/pastetheplan/?id=SJcbLHxO7

jerik1
quelle

Antworten:

23

Warum dieser Index diese Abfrage nicht "abdeckt":

Kein guter Grund. Das ist ein Deckungsindex für diese Abfrage.

Bitte stimmen Sie hier für das Feedback-Element ab: https://feedback.azure.com/forums/908035-sql-server/suggestions/32896348-filtered-index-not-used-when-is-null-and-key-looku

Und als Abhilfe die gehören WhereColumnin den gefilterten Index:

CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn 
ON MyTab (GroupByColumn) include (WhereColumn)
WHERE (WhereColumn IS NULL) 
David Browne - Microsoft
quelle
13
Dies wurde berichtet , vor einem Jahrzehnt von Gail Shaw über. Dann starb Connect. Das nächste, das ich jetzt finden kann, ist feedback.azure.com/forums/908035-sql-server/suggestions/…
Paul White 9
3

Ich hatte das gleiche Problem wie vor einigen Testwochen. Ich habe eine Abfrage mit einem primären Prädikat, die erfordert, dass die zurückgegebenen Ergebnisse eine NULL-Closedatetime haben, und ich habe darüber nachgedacht, einen gefilterten Index zu verwenden, da 25.000 von 2 Millionen Datensätzen NULL sind und diese Zahl sehr bald abnehmen wird.

Der gefilterte Index wurde erst verwendet, nachdem ich einen Microsoft-Support-Artikel gefunden hatte , in dem Folgendes angegeben ist:

Um dieses Problem zu beheben, fügen Sie die als NULL getestete Spalte in die zurückgegebenen Spalten ein. Oder fügen Sie diese Spalte als Include-Spalten in den Index ein.

Das Hinzufügen der Spalte zum Index (oder Include) scheint also die offizielle Antwort der MS zu sein.

SteveO
quelle
1
Es ist eine praktikable Problemumgehung, bis (und wenn) sie es beheben.
ypercubeᵀᴹ