不幸的是,如果不求助于创建物化视图,似乎没有办法为索引创建负过滤器。如果它是可以创建负过滤器,例如你喜欢的人,这将是非常困难的查询优化器“选择”索引的使用,极大地增加所需要的时间找到一个很好的计划。
根据该表的查询模式,您可以简单地创建两个索引。一个用于小于9,一个用于大于这些索引的任一14 可以由查询优化器用于简单地选择WHERE
条款如WHERE 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);
实现此目的的另一种方法可能是:
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);
这将使用在9到14上过滤的索引来排除行。
在我的测试平台上,一个简单的覆盖索引返回最快的行:
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);
或者,对您自己的答案中使用的方法进行更改:
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;
尽管过滤器被编写为连接,但它支持以下列任何一种方式编写的查询(第一种方式效率更高):
StatusID NOT IN (9, 10, 11, 12, 13, 14)
StatusID < 9 OR StatusID > 14
StatusID NOT BETWEEN 9 AND 14