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.
la source
Réponses:
Il existe deux DMF de cache de plan:
sys.dm_exec_query_plan - renvoie les plans mis en cache au format XML, mais uniquement jusqu'à une certaine taille (et uniquement tant qu'ils peuvent être formatés en XML dans SQL Server, ce qui signifie jusqu'à 128 niveaux imbriqués.)
sys.dm_exec_text_query_plan - retourne les plans mis en cache au format texte, de n'importe quelle taille. Mais l'inconvénient est que lorsque les plans sont volumineux, vous ne pouvez pas les convertir en XML dans SQL Server, et même TRY_CONVERT car XML renvoie une valeur nulle.
sp_BlitzCache ne frappe que l'ancien DMV (car il doit analyser les plans de requête en XML pour faire toutes sortes de découpage et de découpage.) J'ai créé le problème Github # 838 pour améliorer cela afin que nous puissions au moins alerter les utilisateurs pour vérifier sys.dm_exec_text_query_plan pour leur de plus grandes requêtes. Cependant, nous ne pourrons toujours pas faire d'analyse XML.
la source
sys.query_store_plan.query_plan
estnvarchar(MAX)
non XML (trivia SQL).Vous avez peut-être besoin d'ajuster la taille maximale du XML qui peut être renvoyé par SSMS à une grille?
la source