20

我正在尝试跟踪数据库中从未使用过或几个月未使用过的所有存储过程。

我想找到一个查询来显示所有未使用的存储过程,以便可以分析这些存储过程以确定是否可以删除它们。

我熟悉 sys.procedures,但不知道如何确定某个程序是否正在使用中。

SELECT *
FROM sys.procedures;

使用 SQL Server 2008 R2。

更新更新更新

使用下面 Aaron Bertrand 的查询,稍作修改,这就是我最终使用的,它是完美的。

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;

感谢您的帮助。

4

3 回答 3

30

DMVs will record stats for procedures, but they only possibly go as far back as the last restart (and often not that far, depending on how long a plan lives in cache):

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;

So if your system has only been up for a short time, this is not a reliable measure. The link @Siva points out is useful as well for some other ideas. Unfortunately SQL Server doesn't really track this for you overall so unless you add tracing or logging you are stuck with the trust you place in the DMV...

EDIT it was a good point, I was solving for the procedures that have run. Instead you may want this:

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;

Or you may want to also include procedures that have run as well, but order them by when they last ran:

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;

This will order first the procedures that haven't run since a restart, then the rest by when they were executed last, oldest first.

于 2012-05-02T20:51:36.713 回答
3

这是对我最有用的公认答案的变体:

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

修改显示上次执行时间并包括过程的模式。

于 2013-07-15T15:32:31.110 回答
1

出于某种原因,我的 dm_exec_procedure_stats 视图一整天都在清除。所以我现在才运行它,最早的执行时间是从今天早上开始的,但我知道我们今天早上没有重新启动 SQL 或其他任何事情。

无论如何,我想创建一个 proc,我可以将它放入一个每小时运行的作业中,并捕获最近运行的 proc。这是我所做的:

创建了一个表来记录执行的过程及其第一次和最后一次执行时间。

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

创建了一个插入或更新 ProcsThatExecute 表的过程。在工作中每小时运行一次,几天、几周或几个月后,您会记录使用了哪些 proc:

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
于 2014-01-10T01:21:53.140 回答