I am trying to track down all stored procedures in a database that have never been used, or that have not been used in many months.
I would like to find a query to show all the stored procedures that are not in use so that those stored procedures can be analyzed to determine if they can be removed.
I am familiar with sys.procedures, but don't know how to determine if a procedure is in use or not.
SELECT *
FROM sys.procedures;
Using SQL Server 2008 R2.
UPDATE UPDATE UPDATE
Using the query from Aaron Bertrand below, slightly modified, this is what I ended up using, and it was perfect.
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;
Thanks for the hlep.
One approach to this is to use the SQL Server Profiler and track what procedures are being called and compare them to the list of what procedures we have, while marking whether the procedures are used or not.
Using SQL Server Management StudioIn Object Explorer, connect to an instance of Database Engine and then expand that instance. Expand Databases, expand the database in which the procedure belongs, and then expand Programmability. Expand Stored Procedures, right-click the procedure and then click View Dependencies.
Using SQL Server Management StudioExpand Stored Procedures, right-click the procedure and then select Script Stored Procedure as, and then select one of the following: Create To, Alter To, or Drop and Create To. Select New Query Editor Window. This will display the procedure definition.
In MySQL, there are two ways to find the names of all tables, either by using the "show" keyword or by query INFORMATION_SCHEMA. In the case of SQL Server or MSSQL, You can either use sys. tables or INFORMATION_SCHEMA to get all table names for a database.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With