Quelles sont les raisons pour lesquelles un plan manque dans le cache pour les procédures stockées?
WITH RECOMPILE
- SQL dynamique
- Code crypté
- Modifications importantes des données
- Mettre à jour les statistiques
- Quoi d'autre?
J'ai récemment travaillé sur 2 serveurs (SQL Server 2008 R2 et SQL Server 2012) qui n'avaient pas de plans en cache pour des procédures stockées très gourmandes en ressources. Beaucoup, peut-être toutes, les instructions à l'intérieur des procédures stockées n'avaient pas non plus de plans en cache. Certaines des procédures stockées s'exécutent assez fréquemment, comme quelques fois par seconde.
Pas de pression mémoire du tout. L'un des serveurs a beaucoup plus de matériel que nécessaire.
Je pensais que les plans manquants étaient dus à des créations de tables temporaires au milieu des procédures stockées, mais cela semble être d'anciennes informations de SQL Server 2000 ou d'une version antérieure. À partir de SQL Server 2005, les recompilations se produisent au niveau de l'instruction pour les instructions après la DDL. Est-ce vrai dans tous les cas ou cela peut-il toujours se produire sur les versions plus récentes?
Quoi d'autre pourrait être le coupable des plans manquants? J'ai survolé quelques articles sur ce sujet, mais rien ne semble convenir.
Optimiser pour les charges de travail ad hoc est activé sur le serveur que je regarde cette semaine. L'une des procédures stockées n'est exécutée qu'une fois par jour. J'ai le code pour celui-là. Je n'ai pas le code de celui qui s'exécute plus de 100 fois par minute, mais je peux l'obtenir. Je ne pourrai pas poster le code, mais je peux le décrire par rapport à ma question.
Je ne pense pas que quiconque libère le cache de procédure ou supprime des tampons propres. Ce client utilise Solarwinds DPA comme l'un de leurs outils de surveillance. DPA a capturé l'un des plans d'exécution de la déclaration dans le proc stocké qui est appelé une fois par jour. Cette déclaration a une quantité massive de lectures en raison de la WHERE
clause non-sargable . Si DPA a capturé la déclaration, il s'agit d'un plan estimé et se trouvait dans le cache du plan à un moment donné. N'est tout simplement pas là lorsque nous dépannons. Je vais les faire commencer à se connecter sp_WhoIsActive
à une table.
J'utilise sp_BlitzCache
. (Je travaille pour Brent Ozar Unlimited) Cela montrera le plan pour la procédure stockée entière ainsi que les plans pour les déclarations individuelles, si elles existent. S'ils n'existent pas, il a ceci pour un avertissement "Nous n'avons pas pu trouver un plan pour cette requête. Les raisons possibles de ceci incluent SQL dynamique, des RECOMPILE
conseils et du code crypté." Et cet avertissement figure également sur les déclarations.
TF 2371 n'est pas en place. Je regarde les statistiques d'attente. Le serveur s'ennuie assez. Le PLE est supérieur à 130 000.
J'ai maintenant le code pour 2 procédures stockées supplémentaires. L'un d'eux utilise SQL dynamique avec exec (@sql)
afin que l'on sache pourquoi il n'y a pas de plan pour cela. Mais l'autre, et c'est celui qui tourne plus de 100 fois par minute, n'a rien d'extraordinaire. La seule chose qui ressort dans celui-ci est que les tables temporaires sont créées au milieu de plus de 1000 lignes de code. Il appelle également un tas de procédures stockées enfants.
En ce qui concerne la mise en cache de plan dans SQL Server 2008 , je ne vois aucun littéral> = 8 Ko, mais l'une des procédures stockées a un commentaire sur une insertion en bloc juste avant d'appeler une autre procédure stockée. Mais l'insertion en vrac n'apparaît pas dans la procédure stockée externe que je regarde. La section "Seuil de recompilation" de l'article est intéressante. Ce que je vois pour les tables temporaires, c'est des tonnes d'INSERTS (qui pourraient entraîner des millions de lignes), quelques mises à jour et suppressions. Donc, beaucoup de données changent dans les tables temporaires. Des millions.