J'ai rencontré une situation étrange où l'ajout OPTION (RECOMPILE)
à ma requête entraîne son exécution en une demi-seconde, tandis que son omission entraîne la durée de la requête bien plus de cinq minutes.
C'est le cas lorsque la requête est exécutée depuis l'Analyseur de requêtes ou depuis mon programme C # via SqlCommand.ExecuteReader()
. Appeler (ou ne pas appeler) DBCC FREEPROCCACHE
ou DBCC dropcleanbuffers
ne fait aucune différence; Les résultats de la requête sont toujours renvoyés instantanément avec OPTION (RECOMPILE)
et plus de cinq minutes sans. La requête est toujours appelée avec les mêmes paramètres [pour le bien de ce test].
J'utilise SQL Server 2008.
Je suis assez à l'aise avec l'écriture de SQL, mais je n'ai jamais utilisé de OPTION
commande dans une requête auparavant et je ne connaissais pas tout le concept des caches de plan avant de scanner les messages sur ce forum. D'après ce que je comprends des messages, c'est OPTION (RECOMPILE)
une opération coûteuse. Cela crée apparemment une nouvelle stratégie de recherche pour la requête. Alors pourquoi est-ce que les requêtes suivantes qui omettent le OPTION (RECOMPILE)
sont si lentes? Les requêtes suivantes ne devraient-elles pas utiliser la stratégie de recherche qui a été calculée lors de l'appel précédent qui incluait l'indication de recompilation?
Est-il très inhabituel d'avoir une requête qui nécessite un indice de recompilation à chaque appel?
Désolé pour la question d'entrée de gamme, mais je ne peux pas vraiment en faire la tête ou la queue.
MISE À JOUR: on m'a demandé de publier la requête ...
select acctNo,min(date) earliestDate
from(
select acctNo,tradeDate as date
from datafeed_trans
where feedid=@feedID and feedDate=@feedDate
union
select acctNo,feedDate as date
from datafeed_money
where feedid=@feedID and feedDate=@feedDate
union
select acctNo,feedDate as date
from datafeed_jnl
where feedid=@feedID and feedDate=@feedDate
)t1
group by t1.acctNo
OPTION(RECOMPILE)
Lors de l'exécution du test à partir de l'Analyseur de requêtes, j'ajoute les lignes suivantes:
declare @feedID int
select @feedID=20
declare @feedDate datetime
select @feedDate='1/2/2009'
Lors de son appel depuis mon programme C #, les paramètres sont transmis via la SqlCommand.Parameters
propriété.
Pour les besoins de cette discussion, vous pouvez supposer que les paramètres ne changent jamais afin que nous puissions exclure un paramètre sous-optimal sentant comme la cause.
X = @X OR @X IS NULL
à X=@X
et effectuer une cherchent Voir ici ou en poussant prédicats plus bas contre une vue avec des fonctions de fenêtre
RECOMPILE
. Dans tous les cas, saisissez les plans d'exécution et examinez les différences.