Theo câu trả lời này , trừ khi một chỉ mục được xây dựng trên các cột được sử dụng để hạn chế, truy vấn sẽ không được hưởng lợi từ một chỉ mục.
Tôi có định nghĩa này:
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
và truy vấn này:
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());
Tôi đã xem xét kế hoạch thực tế và chỉ có một chỉ mục tìm kiếm với vị từ chính xác như trong WHERE
- không có "tra cứu dấu trang" bổ sung nào để truy xuất LastAccessTime
ngay cả khi chỉ mục sau được "đưa" vào chỉ mục, không phải là một phần của chỉ mục.
Đối với tôi có vẻ như hành vi này mâu thuẫn với quy tắc rằng cột phải là một phần của chỉ mục và không chỉ là "bao gồm".
Là hành vi tôi quan sát đúng? Làm cách nào tôi có thể biết trước nếu WHERE
lợi ích của tôi từ một cột được bao gồm hoặc cần cột là một phần của chỉ mục?
(ItemState, CreationTime) INCLUDE (LastAccessTime)
(a,b)
không phải là tốt nhất cho một truy vấn SELECT a FROM t WHERE b=5;
và rằng một chỉ mục trên (b) INCLUDE (a)
là tốt hơn nhiều.
ItemState
giá trị, tuy nhiên Seek sẽ không hiệu quả như thể Index của bạn được cấu trúc như sau(ItemState, CreationTime, LastAccessTime)