web-dev-qa-db-fra.com

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

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:

enter image description here

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]

enter image description here

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
2
Marcello Miorelli

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:

quels éléments du cache de charge de travail ou de plan de requête dois-je consulter pour décider du paramétrage simple ou forcé dans mes bases de données?

3
Marcello Miorelli

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.

1
dogrishin