为什么不使用IS NULL值的筛选索引?


18

假设我们有一个这样的表定义:

CREATE TABLE MyTab (
    ID INT IDENTITY(1,1) CONSTRAINT PK_MyTab_ID PRIMARY KEY
    ,GroupByColumn NVARCHAR(10) NOT NULL
    ,WhereColumn DATETIME NULL
    )

和一个过滤的非聚集索引,如下所示:

CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn ON MyTab 
    (GroupByColumn)
WHERE (WhereColumn IS NULL) 

为什么此索引未针对此查询“覆盖”:

SELECT 
    GroupByColumn
    ,COUNT(*)
FROM MyTab
WHERE WhereColumn IS NULL
GROUP BY GroupByColumn

我正在得到这个执行计划:

在此处输入图片说明

KeyLookup用于WhereColumn IS NULL谓词。

这是计划:https : //www.brentozar.com/pastetheplan/?id=SJcbLHxO7

Answers:


23

为什么此索引未针对此查询“覆盖”:

没有充分的理由。这是该查询的覆盖索引。

请在此处对退款项目进行投票:https : //feedback.azure.com/forums/908035-sql-server/suggestions/32896348-filtered-index-not-used-when-is-null-and-key-looku

而作为一个解决方法包括WhereColumn在过滤索引:

CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn 
ON MyTab (GroupByColumn) include (WhereColumn)
WHERE (WhereColumn IS NULL) 

13
这是十年前盖尔·肖(Gail Shaw )报道的。然后,Connect死了。最近我现在能找到的是feedback.azure.com/forums/908035-sql-server/suggestions/...
保罗·怀特9

3

几周前进行测试时,我遇到了同样的问题。我有一个带有主谓词的查询,该查询要求返回的结果具有NULL的closedatetime,并且考虑过使用过滤索引,因为25K的2M +记录为NULL,并且这个数字很快就会减少。

过滤后的索引没有被使用-我认为是由于“非唯一性”或通用性-直到我找到一条Microsoft支持文章,内容为:

若要解决此问题,请在返回的列中包含经过测试为NULL的列。或者,将此列添加为索引中的包含列。

因此,将列添加到索引(或包含)似乎是MS的官方回复。


1
这是一个可行的解决方法,直到他们(以及是否)修复它为止。
ypercubeᵀᴹ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.