Согласно этому ответу , если индекс не построен по столбцам, которые используются для ограничения, запрос не получит выгоды от индекса.
У меня есть это определение:
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;
и что индекс на (b) INCLUDE (a)
гораздо лучше.
ItemState
значении, однако поиск не будет таким эффективным, как если бы ваш индекс был структурирован следующим образом(ItemState, CreationTime, LastAccessTime)