Wie kann ich die Anzahl der Anrufe pro gespeicherter Prozedur und Zeitspanne überwachen?

10

Um einige Leistungsprobleme zu diagnostizieren, möchte ich besser verstehen, wie oft bestimmte Prozeduren im Vergleich zur Systemleistung aufgerufen werden. Gibt es eine Möglichkeit, die Häufigkeit zu ermitteln, mit der jede Prozedur während einer bestimmten Zeitspanne aufgerufen wurde?

olle
quelle

Antworten:

17

Sie können dies (und mehr) aus Dynamic Management Views (DMVs) abrufen. Versuchen Sie die folgende Abfrage, um Statistiken für eine bestimmte gespeicherte Prozedur abzurufen.

SELECT
    OBJECT_NAME(qt.objectid)
  , qs.execution_count AS [Execution Count]
  , qs.execution_count / DATEDIFF(Second, qs.creation_time, GETDATE()) AS [Calls/Second]
  , qs.total_worker_time / qs.execution_count AS [AvgWorkerTime]
  , qs.total_worker_time AS [TotalWorkerTime]
  , qs.total_elapsed_time / qs.execution_count AS [AvgElapsedTime]
  , qs.max_logical_reads
  , qs.max_logical_writes
  , qs.total_physical_reads
  , DATEDIFF(Minute, qs.creation_time, GETDATE()) AS [Age in Cache]
FROM
    sys.dm_exec_query_stats AS qs
CROSS APPLY 
    sys.dm_exec_sql_text(qs.[sql_handle]) AS qt
WHERE
    qt.[dbid] = DB_ID()
AND qt.objectid = OBJECT_ID('StoredProcedureName')
OPTION (RECOMPILE);

So sehen Sie sich die am häufigsten ausgeführten Prozeduren an:

SELECT
    OBJECT_NAME(qt.objectid)
  , qs.execution_count AS [Execution Count]
  , qs.execution_count / DATEDIFF(Second, qs.creation_time, GETDATE()) AS [Calls/Second]
  , qs.total_worker_time / qs.execution_count AS [AvgWorkerTime]
  , qs.total_worker_time AS [TotalWorkerTime]
  , qs.total_elapsed_time / qs.execution_count AS [AvgElapsedTime]
  , qs.max_logical_reads
  , qs.max_logical_writes
  , qs.total_physical_reads
  , DATEDIFF(Minute, qs.creation_time, GETDATE()) AS [Age in Cache]
FROM
    sys.dm_exec_query_stats AS qs
CROSS APPLY 
    sys.dm_exec_sql_text(qs.[sql_handle]) AS qt
WHERE
    qt.[dbid] = DB_ID()
ORDER BY
    qs.execution_count DESC
OPTION (RECOMPILE);

Die angegebenen Werte sind seit dem letzten Neustart kumulativ. Wenn Sie über einen festgelegten Zeitraum messen möchten, verwenden Sie den folgenden Befehl, um die Wartestatistiken zurückzusetzen.

DBCC SQLPERF("sys.dm_os_wait_stats",CLEAR);

Wenn Sie feste Zeitspannen über den Tag messen möchten, können Sie die Abfrageausgabe über einen Agentenjob in eine Tabelle einspeisen und entweder a) die Werte zwischen zwei Läufen berechnen oder b) die Wartestatistik als letzten Schritt im Agentenjob zurücksetzen .

Alternativ können Sie einen Profiler-Trace erfassen und über Clear Trace ausführen .

Mark Storey-Smith
quelle
Es scheint, dass ich viele zu viele Ergebnisse bekomme, aber nicht genau. Zum Beispiel sehe ich unter der Spalte object_name response mehrere gleiche Objekte, aber die meisten Details sind bis auf wenige Ausnahmen gleich. Übereinstimmende Spaltendetails: ExecutionCount, Call / Second, AgeInCache. Nicht übereinstimmende Spaltendetails: AvgWorkerTime, TotalWorkerTime, AvgElapesedTime. Was würde das viele zu viele Ergebnis verursachen?
Kstubs