Il y a une question similaire, mais ce n'est pas la même:
Le processeur de requêtes n'a pas pu produire un plan de requête
J'ai la requête suivante et l'index filtré suivant, et je ne vois aucune raison pour laquelle la requête ne peut pas utiliser mon index filtré décrit ci-dessous:
- la requête - peu importe si j'utilise le max
ou juste la colonne, il n'aime pas l'indice
SELECT -- MAX(AC1.changeDate)
AC1.changeDate
FROM [dbo].[applicationStateChange] AS ac1 WITH(INDEX(FI_ASC_ChangeDate))
WHERE ac1.applicationID = 130002
AND AC1.newStatus = 'PLC'
- et ceci est mon index filtré - cet index est juste pour optimiser la requête ci-dessus
CREATE NONCLUSTERED INDEX FI_ASC_ChangeDate
ON [dbo].[applicationStateChange] ( applicationID DESC)
INCLUDE ( [changeDate] )
WHERE newStatus = 'PLC'
WITH ( PAD_INDEX = OFF, FILLFACTOR = 100 , SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF, ONLINE = On,
DROP_EXISTING = ON,
DATA_COMPRESSION=PAGE, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON )
ON [NONCLUSTERED_INDEXES]
lorsque j'exécute la requête, y compris le index hint
, Je reçois le message d'erreur suivant:
Msg 8622, niveau 16, état 1, ligne 455 Le processeur de requêtes n'a pas pu produire un plan de requête en raison des indications définies dans cette requête. Renvoyez la requête sans spécifier d'indices et sans utiliser SET FORCEPLAN.
Vous avez manqué quelque chose?
- l'ajout de la colonne newStatus
à l'index n'a pas résolu le problème, ni dans l'index ni dans l'include:
CREATE NONCLUSTERED INDEX FI_ASC_ChangeDate
ON [dbo].[applicationStateChange] ( applicationID DESC, newStatus ASC)
INCLUDE ( [changeDate] )
WHERE newStatus = 'PLC'
WITH ( PAD_INDEX = OFF, FILLFACTOR = 100 , SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF, ONLINE = On,
DROP_EXISTING = ON,
DATA_COMPRESSION=PAGE, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON )
ON [NONCLUSTERED_INDEXES]
CREATE NONCLUSTERED INDEX FI_ASC_ChangeDate
ON [dbo].[applicationStateChange] ( applicationID DESC)
INCLUDE ( [changeDate],newStatus )
WHERE newStatus = 'PLC'
WITH ( PAD_INDEX = OFF, FILLFACTOR = 100 , SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF, ONLINE = On,
DROP_EXISTING = ON,
DATA_COMPRESSION=PAGE, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON )
ON [NONCLUSTERED_INDEXES]
peut-il être le mode de compatibilité?
J'ai remarqué que si je supprime le filter
de l'index, la requête l'accepte bien. Mais ce n'est pas comme ça que j'aimerais.
CREATE NONCLUSTERED INDEX FI_ASC_ChangeDate
ON [dbo].[applicationStateChange] ( applicationID DESC,newStatus
)
INCLUDE ( [changeDate])
--WHERE newStatus = 'PLC'
WITH ( PAD_INDEX = OFF, FILLFACTOR = 100 , SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF, ONLINE = On,
DROP_EXISTING = ON,
DATA_COMPRESSION=PAGE, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON )
ON [NONCLUSTERED_INDEXES]
Voici la définition du tableau en question:
IF OBJECT_ID('[dbo].[applicationStateChange]') IS NOT NULL
DROP TABLE [dbo].[applicationStateChange]
GO
CREATE TABLE [dbo].[applicationStateChange] (
[applicationID] INT NOT NULL,
[changeDate] DATETIME NOT NULL,
[oldStatus] CHAR(3) NULL,
[newStatus] CHAR(3) NULL,
[oldStatusReasonID] INT NULL,
[newStatusReasonID] INT NULL,
[oldStatusReason] VARCHAR(60) NULL,
[newStatusReason] VARCHAR(60) NULL,
[oldOnHold] BIT NULL,
[newOnHold] BIT NULL,
CONSTRAINT [PK_applicationStateChange] PRIMARY KEY CLUSTERED ([applicationID] asc, [changeDate] asc) WITH FILLFACTOR = 90,
CONSTRAINT [FK_applicationStateChange_application] FOREIGN KEY ([applicationID]) REFERENCES [application]([applicationID]))
GO
CREATE NONCLUSTERED INDEX [IX_applicationStateChange_ChangeDate]
ON [dbo].[applicationStateChange] ([changeDate] desc)
CREATE NONCLUSTERED INDEX [FI_ASC_ChangeDate]
ON [dbo].[applicationStateChange] ([applicationID] desc, [changeDate] asc, [newStatus] asc)
WHERE ([newStatus]='PLC')
WITH FILLFACTOR = 100
comme je l'ai vu sur cette réponse lorsque j'ajoute option(recompile)
à ma requête, il fonctionne très bien en acceptant l'index d'index:
SELECT MAX(AC1.changeDate)
-- AC1.changeDate
FROM [dbo].[applicationStateChange] AS ac1 WITH(INDEX(FI_ASC_ChangeDate))
WHERE AC1.newStatus = 'PLC'
OPTION (RECOMPILE)
Toujours quand j'exécute la même requête without
la option(recompile)
j'obtiens la même erreur
Msg 8622, niveau 16, état 1, ligne 479 Le processeur de requête n'a pas pu produire un plan de requête en raison des indications définies dans cette requête. Renvoyez la requête sans spécifier d'indices et sans utiliser SET FORCEPLAN.
Sur mon environnement de test cependant, je pouvais me permettre d'exécuter l'opération suivante et après cela plus de problèmes avec cet index filtré:
ALTER DATABASE [JUNOCORE] SET PARAMETERIZATION SIMPLE;
pour corroborer ma décision de le faire dans le test, j'ai lu les articles suivants:
Paramétrage SQL Server simple et forcé
Résultat Blitz: paramétrage forcé
Maintenant, j'ai envie de changer mon [JUNOCORE] database
Dans LIVE aussi en paramétrage simple
Cela m'amène alors à la question suivante:
Pour les personnes recherchant d'autres raisons possibles de cette erreur:
Dans mon cas, j'ai eu la même erreur avec ma requête où quelqu'un a utilisé avec forceseek indice.
Enfin, j'ai compris que la table était un HEAP
et la création d'un Clustered Index
résolu le problème.