我正在尝试跟踪数据库中从未使用过的所有存储过程,或者在几个月内未使用过的存储过程。
我想找一个查询来显示所有未使用的存储过程,以便可以分析这些存储过程以确定它们是否可以被删除。
我熟悉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。
答案 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