DBCC freeproccache?

Ihre Fragen sind überall, also werde ich versuchen, sie alle zu beantworten. Der Prozedurcache ist nur so groß. Ihr Prozedurcache wurde möglicherweise mit Einwegplänen gefüllt (dies hat keine Auswirkungen auf Statistiken, obwohl Statistiken den Plancache beeinflussen können). Sie können viele Details zu Einwegplänen in Kimberly Tripps Blogbeitrag „Cache planen und für Adhoc-Workloads optimieren“ lesen – einschließlich einer Abfrage für sys.dm_exec_cached_plans, mit der Sie feststellen können, wann der Cache mit vielen Einwegplänen gefüllt ist. Wie sie vorschlägt, können Sie dieses Aufblähen verhindern, indem Sie optimize für Ad-hoc-Workloads verwenden. Wenn Sie dies häufig tun müssen, würde ich sagen, dass das Planen von Freeproccache als Job ein Pflaster und keine Lösung ist.

Um einen „schlechten“ Plan zu löschen, müssen Sie zuerst den „schlechten“ Plan identifizieren. Dies kann ein Plan sein, der eine bestimmte Größe überschreitet und / oder in einiger Zeit nicht ausgeführt wurde oder den Sie durch eine lang andauernde Abfrage identifiziert haben usw. Leider ist es nicht einfach, einen Plan zu identifizieren, der Opfer von Parameter-Sniffing ist, es sei denn, Sie kennen die betroffene Abfrage oder Abfragen bereits. Angenommen, Sie möchten die ältesten Pläne im Cache finden, die seit über einer Woche nicht mehr ausgeführt wurden:

;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;

Jetzt müssen Sie überprüfen, ob Sie diesen Plan wirklich löschen möchten. Wenn Sie diese Abfrage beispielsweise als etwas erkennen, das der CEO morgen ausführen könnte, ist es vielleicht am besten, sie dort zu belassen. Wenn Sie den Plan löschen möchten, können Sie ihn direkt löschen, indem Sie sagen:

DBCC FREEPROCCACHE();

Das klingt nach viel mehr Arbeit als das globale Ausführen von DBCC FREEPROCCACHE, aber wenn Sie viele gute Pläne im Cache haben, wird es für Ihre Benutzer insgesamt sicherlich besser sein.

Trotzdem klingt das wirklich nach einem Pflaster. Wenn sich Ihr Cache mit Junk füllt und die Leistung auf die Toilette geht, bis Sie den Cache freigeben, müssen Sie die Architektur, die Übermittlung von Abfragen usw. auf einer höheren Ebene betrachten. Dies ist das Verhalten, das ich von der allerersten Iteration von LINQ2SQL erwarten würde, bei der eine Version eines Plans für eine Abfrage für jedes Zeichenfolgenargument mit unterschiedlicher Länge zwischengespeichert würde. Wenn Sie also einen Parameter von ‚Januar‘ hätten, würden Sie einen anderen Plan erhalten als mit einem Parameter von ‚Februar‘, da er den Datentyp als VARCHAR(7) vs. VARCHAR(8) definieren würde. Ich bin mir ziemlich sicher, dass das Verhalten behoben ist, aber ich weiß nicht genug über Ihre Umgebung / Anwendung, um vorzuschlagen, wo genau nach „schlechten Ideen“ gesucht werden soll.“