表格如下:
-- int Id, string Name
CREATE TABLE [Clients]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](550) NOT NULL
CONSTRAINT [PK_Clients] PRIMARY KEY CLUSTERED (Id) ASC
)
-- create index on Name, and include Id desc
CREATE NONCLUSTERED INDEX [IX_Clients_Name] ON [Clients]
(
[Name] ASC,
[Id] DESC
)
我将问题缩小到以下简单查询:
DECLARE @filter nvarchar(4000)
SET @filter = N'Johnnie'
-- use the parameter in WHERE clause
-- (this is what EF core basically generates)
SELECT Id, Name
FROM Clients
WHERE Name LIKE @filter + N'%'
ORDER BY Id DESC
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY
-- use hardcoded string clause
SELECT Id, Name
FROM Clients
WHERE Name LIKE N'Johnnie%'
ORDER BY Id DESC
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY
在第一种情况下,实际执行计划显示一个索引
,然后是前10行(扫描所有30000行),而第二行进行索引
寻找
,后跟一个排序(并且只查找单个匹配行)——显然,在这种情况下,第二个更可取,在一般情况下(因为我通常只有两个匹配的名称)。
我更新了统计数据,但没有改变(尽管我不明白为什么会有差异)。
有人能告诉我为什么会有不同吗?
(顺便说一句,如果我删除
ORDER BY ... OFSET ... FETCH