这让我发疯。
考虑一个删除了不相关列的简单表:
create table boxes (
row_id int not null identity(1,1) primary key,
location varchar(15) null,
dismantled bit not null default 0,
rank int not null default 0
/* irrelevant columns, text and numbers */
)
对于某个重要的查询,我想要一个过滤索引:
create nonclustered index anindex ON boxes (rank)
where (dismantled=0 and location is null)
这将创建一个索引,其中包含大约 150k 中的大约 150 条记录。这很好。
现在我们查询表:
select top (1) row_id
from boxes
where dismantled = 0 and location is null
order by rank;
执行计划很奇怪。索引扫描anindex
伴随着书签查找,使用 seekedrow_id
来确认location
是null
. 选择通过查找的记录。
为什么在地球上?location
是null
根据所用索引的定义,不是吗?
现在,如果我做了一件愚蠢的事情并包含location
在过滤索引中......
create nonclustered index anindex ON boxes (location, rank)
where (dismantled=0 and location is null)
然后突然间执行计划很棒,索引搜索anindex
没有查找。
这只是一个例子,每次我想使用过滤索引时都会遇到这个问题。每次我最终被迫将过滤索引的无用字段包含到索引字段列表中时,只有这样服务器才能正确使用索引;否则,它要么扫描它,要么完全忽略它。
是什么赋予了?包含无用字段是推荐的做法吗?
这之前已在 Connect 和Closed 上作为“Won't Fix”提出。
这在我看来非常令人失望。也许对该项目进行投票和评论。
编辑: BOL 有一个在过滤索引中使用的示例,它不执行键查找,但替换为确实会导致查找,因此看起来好像有时它被避免了......
WHERE EndDate IS NOT NULL
IS NOT NULL
IS NULL