DBCC freeproccache?

Vos questions sont partout, alors je vais essayer de les répondre à toutes. Le cache de procédure n’est que si grand. Votre cache de procédures peut avoir été rempli de plans à usage unique (cela n’a aucun impact sur les statistiques, bien que les statistiques puissent avoir un impact sur le cache de plans). Vous pouvez lire de nombreux détails sur les plans à usage unique dans l’article de blog de Kimberly Tripp, « Plan cache and optimizing for adhoc workloads » – y compris une requête sur sys.dm_exec_cached_plans qui aidera à identifier quand le cache est rempli avec beaucoup de plans à usage unique. Comme elle le suggère, vous pouvez éviter ces ballonnements en utilisant optimize pour les charges de travail ad hoc. Si vous trouvez le besoin de le faire souvent, je dirais que la planification de freeproccache en tant que travail est un pansement, pas une solution.

Afin d’éliminer un « mauvais » plan, vous devez d’abord identifier le « mauvais » plan. Il peut s’agir d’un plan qui dépasse une certaine taille et / ou n’a pas été exécuté depuis un certain temps, ou que vous avez identifié par une requête de longue durée, etc. Malheureusement, il n’est pas simple d’identifier un plan victime d’un reniflage de paramètres à moins que vous ne connaissiez déjà la ou les requêtes impactées. Supposons que vous souhaitiez trouver les plans les plus anciens du cache qui n’ont pas été exécutés depuis plus d’une semaine:

;WITH x AS ( SELECT TOP 10 qs., qs.plan_handle, txs = qs.statement_start_offset, txe = qs.statement_end_offset, = cp.size_in_bytes, = SUM(cp.usecounts), = MAX(qs.last_execution_time) FROM sys.dm_exec_query_stats AS qs INNER JOIN sys.dm_exec_cached_plans AS cp ON qs.plan_handle = cp.plan_handle WHERE qs.last_execution_time < DATEADD(DAY, -7, CURRENT_TIMESTAMP) GROUP BY qs., qs.plan_handle, cp.size_in_bytes, qs.statement_start_offset, qs.statement_end_offset ORDER BY DESC) SELECT x.plan_handle, size, uses, , = COALESCE(NULLIF( SUBSTRING(t., x.txs/2, CASE WHEN x.txe = -1 THEN 0 ELSE (x.txe - x.txs)/2 END ), ''), t.) FROM x CROSS APPLY sys.dm_exec_sql_text(x.) AS t;

Maintenant, vous devez vérifier que vous voulez vraiment effacer ce plan. Par exemple, si vous reconnaissez cette requête comme quelque chose que le PDG pourrait exécuter demain, il est peut-être préférable de la laisser là. Si vous souhaitez effacer le plan, vous pouvez l’effacer directement en disant:

DBCC FREEPROCCACHE();

Cela semble beaucoup plus de travail que d’exécuter DBCC FREEPROCCACHE globalement, mais si vous avez beaucoup de bons plans dans le cache, ce sera certainement mieux pour vos utilisateurs dans l’ensemble.

Pourtant, cela ressemble vraiment à un pansement. Si votre cache se remplit de déchets et que les performances vont dans les toilettes jusqu’à ce que vous libériez le cache, vous devez examiner à un niveau supérieur l’architecture, la façon dont les requêtes sont soumises, etc. C’est le comportement que j’attendrais de la toute première itération de LINQ2SQL, où il mettrait en cache une version d’un plan pour une requête pour chaque argument de chaîne d’une longueur différente. Donc, si vous aviez un paramètre de ‘Janvier’, vous obtiendrez un plan différent de celui d’un paramètre de ‘février’ car il définirait le type de données comme VARCHAR(7) vs VARCHAR(8). Assez sûr que ce comportement est corrigé, mais je n’en sais pas assez sur votre environnement / application pour suggérer où chercher précisément les « mauvaises idées. »