Mengapa indeks yang difilter pada nilai IS NULL tidak digunakan?

18

Asumsikan kita memiliki definisi tabel seperti ini:

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

Dan indeks non-clustered yang disaring seperti ini:

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

Mengapa indeks ini tidak "mencakup" untuk permintaan ini:

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

Saya mendapatkan rencana eksekusi ini:

masukkan deskripsi gambar di sini

KeyLookup adalah untuk predikat WhereColumn IS NULL.

Inilah rencananya: https://www.brentozar.com/pastetheplan/?id=SJcbLHxO7

jerik1
sumber

Jawaban:

23

Mengapa indeks ini tidak "mencakup" untuk permintaan ini:

Tidak ada alasan bagus. Itu adalah indeks penutup untuk permintaan itu.

Harap beri suara untuk item yang dikembalikan di sini: https://feedback.azure.com/forums/908035-sql-server/suggestions/32896348-filtered-index-not-used-when-is-null-and-key-looku

Dan sebagai solusinya termasuk WhereColumndalam indeks yang difilter:

CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn 
ON MyTab (GroupByColumn) include (WhereColumn)
WHERE (WhereColumn IS NULL) 
David Browne - Microsoft
sumber
13
Ini dilaporkan lebih dari satu dekade yang lalu oleh Gail Shaw. Kemudian Connect meninggal. Yang terdekat yang bisa saya temukan sekarang adalah feedback.azure.com/forums/908035-sql-server/suggestions/…
Paul White 9
3

Saya memiliki masalah yang sama yang saya pikir ketika melakukan beberapa pengujian minggu lalu. Saya punya pertanyaan dengan predikat utama yang mensyaratkan bahwa hasil yang dikembalikan memiliki NULL closedatetime dan saya berpikir untuk menggunakan indeks yang difilter karena 25K dari catatan 2M + adalah NULL dan angka ini akan berkurang segera.

Indeks yang difilter tidak digunakan - saya berasumsi karena 'non-keunikan' atau kesamaan - sampai saya menemukan artikel dukungan Microsoft yang mengatakan:

Untuk mengatasi masalah ini, sertakan kolom yang diuji sebagai NULL di kolom yang dikembalikan. Atau, tambahkan kolom ini sebagai kolom termasuk dalam indeks.

Jadi menambahkan kolom ke Indeks (atau Sertakan) tampaknya menjadi respons MS resmi.

SteveO
sumber
1
Itu solusi yang layak, sampai kapan (dan jika) mereka memperbaikinya.
ypercubeᵀᴹ