Perché l'indice filtrato sul valore IS NULL non viene utilizzato?


18

Supponiamo di avere una definizione di tabella come questa:

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

E un indice non cluster filtrato come questo:

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

Perché questo indice non "copre" questa query:

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

Ricevo questo piano di esecuzione:

inserisci qui la descrizione dell'immagine

KeyLookup è per il predicato Where Nolumn IS NULL.

Ecco il piano: https://www.brentozar.com/pastetheplan/?id=SJcbLHxO7

Risposte:


23

Perché questo indice non "copre" questa query:

Nessun buon motivo. Questo è un indice di copertura per quella query.

Si prega di votare per l'articolo di rimborso qui: https://feedback.azure.com/forums/908035-sql-server/suggestions/32896348-filtered-index-not-used-when-is-null-and-key-looku

E come soluzione alternativa includere l' WhereColumnindice filtrato:

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

13
Questo è stato riportato oltre un decennio fa da Gail Shaw. Quindi Connect è morto. Il più vicino che posso trovare ora è feedback.azure.com/forums/908035-sql-server/suggestions/…
Paul White 9

3

Ho avuto lo stesso problema che penso quando ho fatto alcuni test settimane fa. Ho una query con un predicato primario che richiede che i risultati restituiti abbiano un tempo chiuso NULL e ho pensato di utilizzare un indice filtrato poiché 25K di record 2M + sono NULL e questa cifra diminuirà molto presto.

L'indice filtrato non è stato utilizzato - ho ipotizzato a causa di "non unicità" o comunanza - fino a quando non ho trovato un articolo di supporto Microsoft che dice:

Per risolvere questo problema, includere la colonna testata come NULL nelle colonne restituite. In alternativa, aggiungi questa colonna come includi colonne nell'indice.

Quindi l'aggiunta della colonna all'Indice (o Includi) sembra essere la risposta ufficiale alla SM.


1
È una soluzione praticabile, fino a quando (e se) lo risolvono.
ypercubeᵀᴹ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.