Durch Ad-hoc-Abfragen aufgeblähter Abfrageplan-Cache, selbst mit "Für Ad-hoc-Workloads optimieren"

7

Ich habe bemerkt, was ich für ungewöhnliche Probleme mit unserem Abfrageplan-Cache hielt, bei dem die Pläne im Cache nie älter als einen Tag waren.

Durch Ausführen der folgenden Abfrage (mit freundlicher Genehmigung von Kimberly Tripp ) wurde festgestellt, dass die Mehrheit der Pläne (4,5 GB von 6 GB zwischengespeicherten Plänen oder 44813 von ~ 50000) Ad-hoc-Abfragen mit einer Verwendungszahl von 1 waren.

SELECT objtype AS [CacheType]
    , count_big(*) AS [Total Plans]
    , sum(cast(size_in_bytes as decimal(18,2)))/1024/1024 AS [Total MBs]
    , avg(usecounts) AS [Avg Use Count]
    , sum(cast((CASE WHEN usecounts = 1 THEN size_in_bytes ELSE 0 END) as decimal(18,2)))/1024/1024 AS [Total MBs - USE Count 1]
    , sum(CASE WHEN usecounts = 1 THEN 1 ELSE 0 END) AS [Total Plans - USE Count 1]
FROM sys.dm_exec_cached_plans
GROUP BY objtype
ORDER BY [Total MBs - USE Count 1] DESC

Ich habe die Problemabfrage (dynamisch, mit einer EXECnatürlich ...) ermittelt, die ziemlich abscheulich, aber auch kompliziert zu beheben ist, und habe daher nach sofortigen Verbesserungen gesucht, die vorgenommen werden könnten.

Die Instanz ist bereits so eingestellt, dass sie die Optimierung für Ad-hoc-Workloads verwendet. Die CacheObjTypevon sys.dm_exec_cached_planssind jedoch alle kompilierte Pläne und nicht kompilierte Plan-Stubs .

Sollten die Pläne bei Verwendung des Ad-hoc-Workload-Modus erst dann kompiliert werden, wenn sie usecountsgrößer als 1 sind? Oder funktioniert das nicht so?

Es gibt auch ein refcountsFeld, auf das sich niemand zu beziehen scheint, wenn es um Ad-hoc-Abfragen geht. Die Refcounts sind immer 1, wenn der Typ Compiled Plan Stub ist, und 2, wenn der Typ Compiled Plan ist . Selbst wenn ich BOL lese , bin ich mir nicht ganz sicher, was dieses Feld bedeutet. Kann jemand klarstellen?

Mark Sinkinson
quelle

Antworten:

6

Nach dieser entfernt der zweite Lauf einer Ad - hoc - Charge den Stummel (die nur einmal verwendet wurde) und erzeugt und speichert den Plan (es zum ersten Mal verwendet wird ).

Ich habe auch nicht viele Verweise auf refcountsandere gesehen, als die Anzahl der Verweise von Cache-Objekten. Ad-hoc-kompilierte Planobjekte können immer noch eine refcount1 haben, sodass dies nicht ausschließlich auf die Persistenz des Plans zurückzuführen ist.

SQLFox
quelle
Damit ich verstehe, was Sie sagen, bedeutet die Anzahl der Benutzer, dass der Plan einmal verwendet wurde, die Abfrage jedoch zweimal ausgeführt wurde. Ein Stub wird also nicht in einen Plan umgewandelt, sondern durch diesen ersetzt?
Mark Sinkinson
4
Über den von @SQLFox bereitgestellten Link - Mit dem kompilierten Plan-Stub kann das Datenbankmodul erkennen, dass dieser Ad-hoc-Stapel zuvor kompiliert wurde, aber nur einen kompilierten Plan-Stub gespeichert hat. Wenn dieser Stapel also erneut aufgerufen (kompiliert oder ausgeführt) wird, wird der Das Datenbankmodul kompiliert den Stapel, entfernt den kompilierten Plan-Stub aus dem Plan-Cache und fügt den vollständig kompilierten Plan dem Plan-Cache hinzu .
Kin Shah