我有一张桌子,当总数大于数字时,需要检查每一分钟以提醒。
SELECT
count(CreatedAt) Total
FROM
Process d
WHERE
d.ProcessedAt is null
AND DATEDIFF(second, GETUTCDATE(), d.CreatedAt) > 30
我的想法是创建一个过滤索引,例如:
CREATE NONCLUSTERED INDEX [FIX_Process_CreatedAt_ProcessedAt] ON [dbo].[Process]
(
[CreatedAt] ASC
)
WHERE ProcessedAt IS NULL
但是看一下执行计划,有一个关键的查找。
我不明白为什么,因为索引有两列用于查询。
任何人都可以解释我为什么吗?
答案 0 :(得分:1)
如果条件为NULL,那么您将只有一个记录集值以及为什么需要该值的索引?它将在什么基础上进行排序?因此,您需要执行过滤索引,其中processedAt不为null,并在代码中使用该条件将有助于
您需要在创建索引脚本
中的INCLUDED列中包含ProcessedAt列添加一个例子来解释@Martin Smith的评论:
表脚本:
Create Table TestKeyLookup
(
id int identity(1,1) primary key -- Created PK which will create clustered Index
,id_for_filteredIndex int NOT NULL
,another_id int NOT NULL
)
插入表记录:
declare @i int = 50
while @i < 1000000
begin
insert into TestKeyLookup (id_for_filteredIndex, another_id) values (@i, @i+5)
set @i = @i + 10
END
在id_for_FilteredIndex列上创建非群集过滤索引,条件位于不同列another_id
create nonclustered index NCI_TestKeyLookup on dbo.TestKeyLookup(id_for_filteredIndex)
where another_id > **673105**
如果我使用完全相同的条件查询表,则优化器不使用KeyLookup
select count(id_for_filteredIndex) from TestKeyLookup with(index(NCI_TestKeyLookup))
where another_id > 673105
如果我通过增加偶数+5或10来改变条件,那么它会将keyLookup改为聚集索引
select count(id_for_filteredIndex) from TestKeyLookup with(index(NCI_TestKeyLookup))
where another_id > 673110
我试图解释这个..如果条件有变化,那么它使用KeyLookup来获取。在某种程度上,如果列可以为空并且它具有空值,则它是正确的,那么它是不同的