Laut dieser Antwort profitiert die Abfrage nicht von einem Index, es sei denn, ein Index wird über die Spalten erstellt, die zum Einschränken verwendet werden.
Ich habe diese Definition:
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
und diese Abfrage:
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());
Ich habe den tatsächlichen Plan überprüft, und es gibt nur eine Indexsuche mit dem Prädikat genau wie in WHERE
- keine zusätzlichen "Lesezeichensuchen", die abgerufen werden müssen LastAccessTime
, obwohl letztere nur im Index "enthalten" sind und nicht Teil des Index.
Es sieht für mich so aus, als ob dieses Verhalten der Regel widerspricht, dass die Spalte Teil des Index sein muss und nicht nur "enthalten" ist.
Ist das Verhalten, das ich beobachte, das richtige? Wie kann ich im Voraus feststellen, ob meine WHERE
Leistungen von einer eingeschlossenen Spalte profitieren oder ob die Spalte Teil des Index sein muss?
(ItemState, CreationTime) INCLUDE (LastAccessTime)
(a,b)
ist nicht das beste für eine Abfrage mit SELECT a FROM t WHERE b=5;
und ein Index für (b) INCLUDE (a)
ist viel besser.
ItemState
Wert suchen , aber die Suche wird nicht so effizient sein, als ob Ihr Index wie folgt strukturiert wäre(ItemState, CreationTime, LastAccessTime)