it-swarm.com.de

TSQL-Abfrage, um nicht verwendete gespeicherte Prozeduren zu finden

Ich versuche, alle gespeicherten Prozeduren in einer Datenbank aufzuspüren, die noch nie verwendet wurden oder seit vielen Monaten nicht verwendet wurden.

Ich möchte eine Abfrage finden, um alle gespeicherten Prozeduren anzuzeigen, die nicht verwendet werden, sodass diese gespeicherten Prozeduren analysiert werden können, um festzustellen, ob sie entfernt werden können.

Ich bin mit sys.procedures vertraut, weiß aber nicht, wie ich feststellen kann, ob eine Prozedur verwendet wird oder nicht.

SELECT *
FROM sys.procedures;

Verwenden von SQL Server 2008 R2.

UPDATE UPDATE UPDATE

Ich habe die Frage von Aaron Bertrand verwendet, etwas modifiziert, das ist es, was ich am Ende verwendet habe, und es war perfekt.

SELECT p.*
  FROM sys.procedures AS p
  LEFT JOIN sys.dm_exec_procedure_stats AS s ON s.[object_id] = p.[object_id]
 WHERE s.object_id IS NULL;

Danke für die hlep.

18
Steve Stedman

DMVs zeichnen Statistiken für Prozeduren auf, die jedoch möglicherweise nur bis zum letzten Neustart zurückgehen (und oft nicht so weit, je nachdem, wie lange ein Plan im Cache gespeichert ist):

SELECT * FROM sys.dm_exec_procedure_stats AS s
INNER JOIN sys.procedures AS p
ON s.[object_id] = p.[object_id]
ORDER BY p.name;

Wenn Ihr System also nur kurze Zeit in Betrieb war, ist dies keine zuverlässige Maßnahme. Der Link @Siva weist darauf hin, dass er auch für andere Ideen nützlich ist. Leider verfolgt SQL Server dies nicht wirklich für Sie. Wenn Sie also keine Ablaufverfolgung oder Protokollierung hinzufügen, bleiben Sie beim Vertrauen in die DMV hängen ...

EDITes war ein guter Punkt, ich habe nach den Prozeduren gesucht, die have ausführen. Stattdessen möchten Sie vielleicht Folgendes:

SELECT sc.name, p.name 
FROM sys.procedures AS p
INNER JOIN sys.schemas AS sc
  ON p.[schema_id] = sc.[schema_id]
LEFT OUTER JOIN sys.dm_exec_procedure_stats AS st
  ON p.[object_id] = st.[object_id]
WHERE st.[object_id] IS NULL
ORDER BY p.name;

Oder Sie möchten auch Prozeduren einbeziehen, die ebenfalls ausgeführt wurden, aber sie nach dem letzten Lauf ordnen:

SELECT sc.name, p.name 
FROM sys.procedures AS p
INNER JOIN sys.schemas AS sc
  ON p.[schema_id] = sc.[schema_id]
LEFT OUTER JOIN sys.dm_exec_procedure_stats AS st
ON p.[object_id] = st.[object_id]
ORDER BY st.last_execution_time, p.name;

Dadurch werden zuerst die Prozeduren angeordnet, die seit einem Neustart nicht mehr ausgeführt wurden, und dann der Rest, der zuletzt ausgeführt wurde, der älteste zuerst.

27
Aaron Bertrand

Hier ist eine Variante der akzeptierten Antwort, die mir am nützlichsten war:

SELECT sc.NAME + '.' + p.NAME [Procedure]
    ,s.last_execution_time
FROM sys.procedures AS p
LEFT JOIN sys.dm_exec_procedure_stats AS s ON p.[object_id] = s.[object_id]
INNER JOIN sys.schemas sc ON p.schema_id = sc.schema_id
ORDER BY s.last_execution_time
    ,sc.NAME
    ,p.NAME

Die Änderungen zeigen die letzte Ausführungszeit an und enthalten das Schema der Prozedur.

2
Ronnie Overby

Aus irgendeinem Grund klärt sich meine Ansicht von dm_exec_procedure_stats im Laufe des Tages. Also habe ich es gerade ausgeführt und die frühesten Ausführungszeiten sind von heute morgen, aber ich weiß, dass wir SQL heute morgen nicht neu gestartet haben.

Jedenfalls wollte ich ein Proc erstellen, das ich in einen Job stecken könnte, um jede Stunde auszuführen und zu erfassen, welche Procs kürzlich ausgeführt wurden. Folgendes habe ich getan:

Es wurde eine Tabelle erstellt, in der die ausgeführten Prozeduren sowie deren erste und letzte Ausführungszeit protokolliert werden.

create table ProcsThatExecute (procName varchar(500), firstExecutionTime datetime, lastExecutionTime datetime)

Es wurde eine Prozedur erstellt, die die ProcsThatExecute-Tabelle einfügt oder aktualisiert. Führen Sie dies stundenweise in einem Job aus und nach ein paar Tagen, Wochen oder Monaten haben Sie ein Protokoll, von dem die Procs verwendet werden:

alter procedure LogProcsThatExecute as begin

    --If they don't already exist in this table, add them.
    insert into ProcsThatExecute(procName, firstExecutionTime, lastExecutionTime)
    SELECT p.NAME ProcName, s.last_execution_time, null
    FROM sys.procedures AS p
        LEFT OUTER JOIN sys.dm_exec_procedure_stats AS s ON p.[object_id] = s.[object_id]
    where not exists (
        select 1 from ProcsThatExecute pte where pte.procName = p.name
    ) and last_execution_time is not null


    --If they do exist in this table, update the last execution time.
    update ProcsThatExecute set lastExecutionTime = s.last_execution_time
    from ProcsThatExecute pte
    inner join sys.procedures AS p on pte.procName = p.name
        LEFT OUTER JOIN sys.dm_exec_procedure_stats AS s ON p.[object_id] = s.[object_id]
    where s.last_execution_time is not null

end
0
Trevor