Selon cette réponse , à moins qu'un index ne soit construit sur les colonnes qui sont utilisées pour restreindre, la requête ne bénéficiera pas d'un index.
J'ai cette définition:
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
et cette requête:
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());
J'ai passé en revue le plan réel, et il n'y a qu'une seule recherche d'index avec le prédicat exactement comme dans le WHERE
- aucune "recherche de signet" supplémentaire à récupérer LastAccessTime
même si ce dernier est seulement "inclus" dans l'index, ne fait pas partie de l'index.
Il me semble que ce comportement contredit la règle selon laquelle la colonne doit faire partie de l'index, et pas seulement "incluse".
Le comportement que j'observe est-il le bon? Comment puis-je savoir à l'avance si mes WHERE
avantages d'une colonne incluse ou si la colonne doit faire partie de l'indice?
(ItemState, CreationTime) INCLUDE (LastAccessTime)
(a,b)
n'est pas le meilleur pour une requête avec SELECT a FROM t WHERE b=5;
et qu'un index sur (b) INCLUDE (a)
est bien meilleur.
ItemState
valeur, mais la recherche ne sera pas aussi efficace que si votre indice était structuré comme suit(ItemState, CreationTime, LastAccessTime)