Leider scheint es keine Möglichkeit zu geben, einen Negativfilter für einen Index zu erstellen, ohne eine materialisierte Ansicht zu erstellen. Wenn es ist möglich , einen negativen Filter wie das zu schaffen Sie mögen, wäre es ziemlich schwierig sein , für die Abfrage-Optimierer des Index für die Verwendung „Pick“, drastisch zu erhöhen die Zeit , einen guten Plan zu finden , erforderlich.
Abhängig von den Abfragemustern für diese Tabelle können Sie einfach zwei Indizes erstellen. einer für weniger als 9 und einer für mehr als 14. Jeder dieser Indizes kann vom Abfrageoptimierer für einfache WHERE
Klauseln wie zWHERE 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);
Ein anderer Weg, dies zu erreichen, könnte sein:
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);
Dies verwendet den nach 9 bis 14 gefilterten Index, um Zeilen auszuschließen.
Auf meinem Prüfstand gibt ein einfacher Abdeckungsindex Zeilen bei weitem am schnellsten zurück:
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);
Alternativ können Sie eine Variation des in Ihrer eigenen Antwort verwendeten Ansatzes verwenden :
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;
Obwohl der Filter als Konjunktion geschrieben wird, unterstützt er Abfragen, die auf eine der folgenden Arten geschrieben wurden (die erste ist etwas effizienter):
StatusID NOT IN (9, 10, 11, 12, 13, 14)
StatusID < 9 OR StatusID > 14
StatusID NOT BETWEEN 9 AND 14