小编Twi*_*mes的帖子

为什么我看到的是所有读取行的键查找,而不是所有与 where 子句匹配的行?

我有一个如下表:

create table [Thing]
(
    [Id] int constraint [PK_Thing_Id] primary key,
    [Status] nvarchar(20),
    [Timestamp] datetime2,
    [Foo] nvarchar(100)
)
Run Code Online (Sandbox Code Playgroud)

Status在和字段上使用非聚集、非覆盖索引Timestamp

create nonclustered index [IX_Status_Timestamp] on [Thing] ([Status], [Timestamp] desc)
Run Code Online (Sandbox Code Playgroud)

如果我查询这些行的“页面”,使用偏移/获取如下,

select * from [Thing]
where Status = 'Pending'
order by [Timestamp] desc
offset 2000 rows
fetch next 1000 rows only
Run Code Online (Sandbox Code Playgroud)

我知道该查询需要读取总共 3000 行才能找到我感兴趣的 1000 行。然后我希望它对这 1000 行中的每一行执行键查找以获取索引中未包含的字段。

但是,执行计划表明它正在对所有 3000 行进行键查找。我不明白为什么,当唯一的条件(按[状态]过滤和按[时间戳]排序)都在索引中时。

在此输入图像描述

如果我用 cte 重新表述查询,如下所示,我或多或少会得到我期望第一个查询执行的操作:

with ids as
(
    select Id from [Thing]
    where Status = 'Pending'
    order by [Timestamp] …
Run Code Online (Sandbox Code Playgroud)

sql-server nonclustered-index bookmark-lookup pagination

14
推荐指数
1
解决办法
765
查看次数