【问题标题】:TSQL query to find un-used stored proceduresTSQL 查询以查找未使用的存储过程
【发布时间】:2012-05-02 20:47:18
【问题描述】:

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

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

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

感谢您的帮助。

【问题讨论】:

  • 对不起 Siva,这不是我想要的。下面亚伦的答案做到了。

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


【解决方案1】:

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 的信任所困......

EDIT 这是一个很好的观点,我正在解决 运行的程序。相反,您可能想要这个:

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;

这将首先对自重新启动后未运行的过程进行排序,然后将其余的按最后执行的时间排序,最旧的在前。

【讨论】:

  • 亚伦,谢谢。你给我的东西真的很接近,只需稍加改动,它就完全符合我的要求。 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;
  • 是的,我明白这只是回到上次重启。这对我来说很好。谢谢!
  • 我会不会“这只是回到上次重启”。这个 is 缓存毕竟是缓存并且缓存总是在运动中(东西进来和出去)。请在此处查看@JeffModen 的回复:stackoverflow.com/a/13506187/555798
  • @MikeTeeVee 是的,我的意思是他们可能早点去。在所有情况下,我都没有尝试将其作为完整且详尽的库存出售。新的措辞让你更快乐?
【解决方案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

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

【讨论】:

    【解决方案3】:

    出于某种原因,我的 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-23
      • 1970-01-01
      • 2018-11-09
      • 2016-02-25
      • 1970-01-01
      相关资源
      最近更新 更多