Відповідно до цієї відповіді , якщо індекс не побудований над стовпцями, які використовуються для обмеження, запит не матиме користі від індексу.
У мене таке визначення:
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)