Menurut jawaban ini , kecuali indeks dibangun di atas kolom yang digunakan untuk membatasi, kueri tidak akan mendapat manfaat dari indeks.
Saya memiliki definisi ini:
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
dan pertanyaan ini:
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());
Saya meninjau rencana yang sebenarnya, dan hanya ada satu pencarian indeks dengan predikat persis seperti di WHERE
- tidak ada "pencarian bookmark" tambahan untuk mengambil LastAccessTime
meskipun yang terakhir hanya "termasuk" ke dalam indeks, bukan bagian dari indeks.
Menurut saya perilaku ini bertentangan dengan aturan bahwa kolom harus menjadi bagian dari indeks, dan bukan hanya "termasuk".
Apakah perilaku yang saya amati itu benar? Bagaimana saya bisa tahu sebelumnya jika WHERE
manfaat saya dari kolom yang disertakan atau membutuhkan kolom untuk menjadi bagian dari indeks?
(ItemState, CreationTime) INCLUDE (LastAccessTime)
(a,b)
bukan yang terbaik untuk kueri SELECT a FROM t WHERE b=5;
dan indeks aktif (b) INCLUDE (a)
jauh lebih baik.
ItemState
nilai, tetapi pencarian tidak akan seefisien jika Indeks Anda disusun sebagai berikut(ItemState, CreationTime, LastAccessTime)