Sayangnya, sepertinya tidak ada cara untuk membuat filter negatif untuk indeks, tanpa menggunakan tampilan yang terwujud. Jika tidak mungkin untuk membuat filter negatif seperti yang Anda inginkan, itu akan cukup sulit untuk query-optimizer untuk "memilih" indeks untuk digunakan, secara drastis meningkatkan waktu yang diperlukan untuk menemukan sebuah rencana yang baik.
Bergantung pada pola kueri untuk tabel ini, Anda cukup membuat dua indeks; satu untuk kurang dari 9 dan satu untuk lebih besar dari 14. Salah satu dari indeks ini dapat dipilih oleh pengoptimal permintaan untuk WHERE
klausa sederhana sepertiWHERE StatusID = 6
CREATE TABLE dbo.TestNegativeFilter
(
TestNegativeFilter INT NOT NULL
CONSTRAINT PK_TestNegativeFilter
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, StatusID INT NOT NULL
);
GO
CREATE INDEX IX_TestNagativeFilter_LessThan9
ON dbo.TestNegativeFilter(StatusID)
WHERE (StatusID < 9);
CREATE INDEX IX_TestNagativeFilter_GreaterThan14
ON dbo.TestNegativeFilter(StatusID)
WHERE (StatusID > 14);
Cara lain untuk mencapai hal ini mungkin:
CREATE INDEX IX_TestNegativeFilter_9_to_14
ON dbo.TestNegativeFilter(StatusID)
WHERE (StatusID IN (9, 10, 11, 12, 13, 14));
SELECT *
FROM dbo.TestNegativeFilter tnf
EXCEPT
SELECT *
FROM dbo.TestNegativeFilter tnf
WHERE tnf.StatusID IN (9, 10, 11, 12, 13, 14);
Ini menggunakan indeks yang difilter pada 9 hingga 14 untuk mengecualikan baris.
Di rig pengujian saya, indeks penutup sederhana mengembalikan baris sejauh yang tercepat:
CREATE NONCLUSTERED INDEX IX_TestNegativeFilter_StatusID
ON dbo.TestNegativeFilter(StatusID)
INCLUDE (TestNegativeFilter);
SELECT *
FROM dbo.TestNegativeFilter tnf
WHERE tnf.StatusID NOT IN (9, 10, 11, 12, 13, 14);
Atau, gunakan variasi pada pendekatan yang digunakan dalam jawaban Anda sendiri :
CREATE INDEX [IX dbo.TestNegativeFilter StatusID not 9-14]
ON dbo.TestNegativeFilter (StatusID)
WHERE StatusID <> 9
AND StatusID <> 10
AND StatusID <> 11
AND StatusID <> 12
AND StatusID <> 13
AND StatusID <> 14;
Meskipun filter ditulis sebagai konjungsi, ia mendukung kueri yang ditulis dengan salah satu cara berikut (yang pertama menjadi sedikit lebih efisien):
StatusID NOT IN (9, 10, 11, 12, 13, 14)
StatusID < 9 OR StatusID > 14
StatusID NOT BETWEEN 9 AND 14