SQL查询以查找未使用的存储过程

时间:2012-05-02 20:47:19

标签: sql-server tsql sql-server-2008-r2

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

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

我熟悉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;

感谢hlep。

3 个答案:

答案 0 :(得分:28)

DMV将记录程序的统计数据,但它们可能只能追溯到最后一次重启(通常不会那么远,具体取决于计划在缓存中存在的时间长度):

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;

因此,如果您的系统只运行了很短的时间,这不是一个可靠的措施。 @Siva指出的链接对于其他一些想法也很有用。不幸的是,SQL Server并没有真正为您提供此跟踪,因此除非您添加跟踪或日志记录,否则您将无法放置在DMV中的信任......

编辑这是一个很好的观点,我正在解决已经运行的程序。相反,你可能想要这个:

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;

或者您可能还希望包含已运行的程序,但在上次运行时按顺序排序:

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;

这将首先命令自重启以来没有运行的程序,然后是最后执行的程序,最先执行的程序。

答案 1 :(得分:2)

以下是对我来说最有用的接受答案的变体:

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

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

答案 2 :(得分:0)

出于某种原因,我的dm_exec_procedure_stats视图会在当天清除。所以我现在就运行它,最早的执行时间是从今天早上开始,但我知道我们今天早上没有重启SQL或其他任何东西。

无论如何,我想创建一个proc,我可以把它放到一个工作中,每小时运行一次并捕获最近运行的那些proc。这是我做的:

创建一个表来记录执行的proc以及它们的第一次和最后一次执行时间。

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

创建了一个插入或更新ProcsThatExecute表的过程。在工作中每小时运行一次,几天或几周或几个月后,您将获得使用哪些操作的日志:

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