Bagaimana cara mengindeks untuk permintaan ketidaksetaraan?

10

Saya memiliki kueri yang mengecualikan data berdasarkan nilai kolom float

select * 
from My_Table
where my_Float_column != 0 and my_Float_column is not null

Saya tidak ingin mengindeks tipe float jika saya dapat membantu. Apakah rencana pelaksanaannya cukup pintar untuk menggunakan indeks yang difilter seperti di bawah ini (Di mana saya hanya mengindeks nilai 0 dan nol) untuk meningkatkan kinerja?

CREATE NONCLUSTERED INDEX IX_My_Table_Float_Filtered
    ON My_Table (my_Float_column)
    WHERE my_Float_column = 0 or my_Float_column is null
Neil P
sumber

Jawaban:

11

Apakah rencana pelaksanaannya cukup pintar untuk menggunakan indeks yang difilter seperti di bawah ini (Di mana saya hanya mengindeks nilai 0 dan nol) untuk meningkatkan kinerja?

Tidak. Tidak ada dukungan langsung dalam SQL Server untuk jenis penolakan baris operator tunggal yang tampaknya ada dalam pikiran Anda.

Berbicara lebih umum, indeks yang difilter tidak secara langsung membantu permintaan yang diberikan, dan toh bukan definisi indeks yang valid. Anda bisa membuat tampilan yang diindeks berisi predikat itu, tetapi masih tidak akan membantu sebagai cara untuk menemukan baris untuk permintaan target. Anda bisa menulis ulang kueri untuk menggunakan tampilan yang diindeks untuk mengecualikan baris yang diambil dengan pemindaian penuh yang terpisah, tetapi sulit untuk melihat bagaimana itu akan menjadi ide yang baik secara umum.

Yang terdekat dengan Anda mungkin adalah pemindaian tampilan yang diindeks yang menggunakan filter bitmap, dengan filter yang diterapkan sebagai bagian dari pemindaian penuh tabel target. Mungkin sulit untuk mendapatkan bentuk rencana kueri ini dengan andal.

Anda juga bisa menggunakan kolom yang dihitung tetap diindeks menggunakan CASEekspresi, tetapi sekali lagi ini akan membutuhkan penulisan ulang permintaan asli, dan akan membutuhkan penyimpanan untuk setiap baris dalam tabel, ditambah indeks.

Dari informasi yang diberikan, tampaknya yang terbaik yang dapat Anda lakukan adalah mendefinisikan indeks sebagai:

CREATE NONCLUSTERED INDEX IX_dbo_My_Table__Float_Filtered
ON dbo.My_Table (my_Float_column)
WHERE 
    my_Float_column <> 0 
    AND my_Float_column IS NOT NULL;
Paul White 9
sumber