La requête s'exécute lentement avec l'expression de la date, mais rapidement avec la chaîne littérale
Je suis en cours d'exécution d'une requête avec dessous de la condition dans SQL Server 2008.
Where FK.DT = CAST(DATEADD(m, DATEDIFF(m, 0, getdate()), 0) as DATE)
Requête prend une éternité à courir avec la condition ci-dessus, mais si juste dire
Where FK.DT = '2013-05-01'
il fonctionne bien dans les 2 minutes. FK.DT
clé contient que des valeurs de données de départ du mois.
Toute aide, je suis juste un ignorant, pourquoi ce qui se passe.
source d'informationauteur user2158642 | 2013-08-14
Vous devez vous connecter pour publier un commentaire.
Ce qui pourrait mieux fonctionner:
Sauf si vous êtes en cours d'exécution avec l'indicateur de trace 4199 sur il y a un bug qui affecte les estimations de cardinalité. Au moment de la rédaction
Retourne
Le bug, c'est que le prédicat en question utilise la date de la première plutôt que la seconde lorsque dériver les estimations de cardinalité. Donc, pour la suite de l'installation.
Requête 1
Estime que le nombre de lignes correspondantes seront de 100 000. C'est le nombre qui correspond à la date
'1786-06-01'
.Mais les deux requêtes suivantes
Donner à ce plan
En raison de la beaucoup plus précis estimations de cardinalité le plan maintenant, juste un index de recherche plutôt que d'une analyse complète.
Dans la plupart des cas, le ci-dessous s'applique probablement. Dans ce spécifiques cas, c'est un optimiseur de bug impliquant
DATEDIFF
. Détails ici et ici. Désolé de douter de t-clausen.dk, mais sa réponse n'était tout simplement pas une interface intuitive et logique de la solution sans en connaître l'existence du bug.Donc en supposant
DT
est en faitDATE
et pas quelque chose de stupide commeVARCHAR
ou - pire encore -NVARCHAR
- c'est probablement parce que vous avez un plan de mise en cache utilisée très différente de la date de valeur lors de la première exécuté, a donc choisi un plan de restauration très différents typique de distribution de données. Il existe des moyens de surmonter ce:La Force d'une recompilation du plan par l'ajout de
OPTION (RECOMPILE)
. Vous pourriez seulement avoir à le faire une fois, mais le plan que vous obtenez peut-être pas optimal pour d'autres paramètres. L'inconvénient de laisser cette option là tout le temps, c'est que vous ensuite de payer le coût de compilation à chaque fois que la requête s'exécute. Dans beaucoup de cas, ce n'est pas substantielle, et je vais souvent choisir de payer connus, à faible coût, plutôt que d'avoir parfois une requête qui tourne légèrement plus vite, et d'autres fois il fonctionne extrêmement lent.Utiliser une variable de première (pas besoin d'un explicite
CONVERT
àDATE
ici, et s'il vous plaît utiliserMONTH
au lieu de sténographie commem
- que l'habitude peut conduire à de vrais drôle de comportement si vous n'avez pas mémorisé ce que tous les abréviations, par exemple, je pariey
etw
ne produisent pas les résultats que vous attendez):Mais dans ce cas, la même chose pourrait se produire - la détection des paramètres pourrait contraindre un sous-optimale à utiliser pour les différents paramètres représentant les différentes données de l'inclinaison.
Vous pouvez également expérimenter avec
OPTION (OPTIMIZE FOR (@dt = '2013-08-01'))
qui permettrait de contraindre SQL Server en considérant cette valeur à la place de celui qui a été utilisé pour compiler le plan de mise en cache, mais cela nécessiterait une chaîne codée en dur littérale, qui va seulement vous aider pour le reste du mois d'août, au point où vous auriez besoin de mettre à jour la valeur. Vous pourriez aussi envisager deOPTION (OPTIMIZE FOR UNKNOWN)
.