根据此答案,除非在用于限制的列上建立索引,否则查询将不会从索引中受益。
我有这个定义:
CREATE TABLE [dbo].[JobItems] (
[ItemId] UNIQUEIDENTIFIER NOT NULL,
[ItemState] INT NOT NULL,
[ItemPriority] INT NOT NULL,
[CreationTime] DATETIME NULL DEFAULT GETUTCDATE(),
[LastAccessTime] DATETIME NULL DEFAULT GETUTCDATE(),
-- other columns
);
CREATE UNIQUE CLUSTERED INDEX [JobItemsIndex]
ON [dbo].[JobItems]([ItemId] ASC);
GO
CREATE INDEX [GetItemToProcessIndex]
ON [dbo].[JobItems]([ItemState], [ItemPriority], [CreationTime])
INCLUDE (LastAccessTime);
GO
和这个查询:
UPDATE TOP (150) JobItems
SET ItemState = 17
WHERE
ItemState IN (3, 9, 10)
AND LastAccessTime < DATEADD (day, -2, GETUTCDATE())
AND CreationTime < DATEADD (day, -2, GETUTCDATE());
我查看了实际的计划,并且只有一个谓词与“完全”中的谓词完全一样WHERE
-没有额外的“书签查找”来检索,LastAccessTime
即使后者只是“包含”在索引中,而不是索引的一部分。
在我看来,这种行为与列必须是索引的一部分而不仅仅是“包含”的规则相矛盾。
我观察到的行为是正确的吗?我如何提前知道我是WHERE
从包含列中受益还是需要该列成为索引的一部分?
(ItemState, CreationTime) INCLUDE (LastAccessTime)
(a,b)
并不是最适合使用的查询,SELECT a FROM t WHERE b=5;
索引on (b) INCLUDE (a)
更好。
ItemState
值进行搜索,但是“搜索”的效率不如您的索引结构如下(ItemState, CreationTime, LastAccessTime)