为什么覆盖过滤索引进行查找
Why a coverage filtered index do a Lookup
我有一个 table 需要每分钟检查一次,以便在总数大于某个数字时发出警报。
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
但是看执行计划,有一个key lookup
我不明白为什么,因为索引有两列用于查询。
谁能解释一下为什么?
如果条件为 NULL,那么记录集将只有一个值,为什么需要该值的索引?它会根据什么进行排序?因此,您需要在 processedAt 不为 null 的情况下执行过滤索引,并在代码中使用该条件将有所帮助
您需要在创建索引脚本的 INCLUDED 列中包含 ProcessedAt 列
添加示例来解释@Martin Smith 的评论:
Table 脚本:
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
)
插入 table 条记录:
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**
如果我使用完全相同的条件查询 table,则优化器未使用 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 来获取。在某种程度上,如果该列可以为空并且它具有空值那么它是不同的
我有一个 table 需要每分钟检查一次,以便在总数大于某个数字时发出警报。
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
但是看执行计划,有一个key lookup
我不明白为什么,因为索引有两列用于查询。
谁能解释一下为什么?
如果条件为 NULL,那么记录集将只有一个值,为什么需要该值的索引?它会根据什么进行排序?因此,您需要在 processedAt 不为 null 的情况下执行过滤索引,并在代码中使用该条件将有所帮助
您需要在创建索引脚本的 INCLUDED 列中包含 ProcessedAt 列
添加示例来解释@Martin Smith 的评论:
Table 脚本:
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
)
插入 table 条记录:
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**
如果我使用完全相同的条件查询 table,则优化器未使用 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 来获取。在某种程度上,如果该列可以为空并且它具有空值那么它是不同的