2012-05-02 19 views
17

Estoy intentando rastrear todos los procedimientos almacenados en una base de datos que nunca se han utilizado o que no se han utilizado en muchos meses.Consulta de TSQL para encontrar procedimientos almacenados no utilizados

Me gustaría encontrar una consulta para mostrar todos los procedimientos almacenados que no están en uso para que esos procedimientos almacenados puedan analizarse para determinar si se pueden eliminar.

Estoy familiarizado con sys.procedures, pero no sé cómo determinar si un procedimiento está en uso o no.

SELECT * 
FROM sys.procedures; 

Uso de SQL Server 2008 R2.

ACTUALIZACIÓN ACTUALIZACIÓN ACTUALIZACIÓN

Usando la consulta de Aaron Bertrand abajo, ligeramente modificada, esto es lo que terminé usando, y fue perfecto.

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; 

Gracias por la hlep.

+0

Lo siento, Siva, eso no es exactamente lo que estaba buscando. La respuesta de Aaron debajo lo hizo. –

Respuesta

26

DMV registrarán estadísticas para los procedimientos, pero sólo posiblemente ir tan lejos como el último reinicio (y muchas veces no tan lejos, dependiendo de cuánto tiempo un plan vive en caché):

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; 

Así que si su sistema solo ha estado funcionando por un corto tiempo, esta no es una medida confiable. El enlace @Siva señala que es útil también para algunas otras ideas. Desafortunadamente SQL Server no tiene realmente un seguimiento de esto para usted por lo general a menos que agregue el rastreo o registro le pegan con la confianza que deposita en el DMV ...

EDITAR que era un buen momento, estaba despejando los procedimientos que tienen ejecutar. En su lugar es posible que desee esto:

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; 

O es posible que desee incluir también los procedimientos que se han ejecutado también, pero para ellos por la última vez que corrió:

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; 

Esto ordenará en primer lugar los procedimientos que no se han ejecutado desde un reinicio, luego el resto cuando se ejecutaron por última vez, primero el más antiguo.

+0

Aaron, gracias. Lo que me diste fue muy cercano, con un pequeño cambio hizo exactamente lo que estaba buscando. SELECCIONE 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; –

+0

Sí, entiendo que esto solo es posterior al último reinicio. Eso es muy bueno para mí. ¡Gracias! –

+0

No ** dijera ** "esto solo ha vuelto al último reinicio" _. Este ** _ es _ ** caché después de todo y el caché siempre está en movimiento (cosas que entran y salen). Por favor, consulte la respuesta de @ JeffModen aquí: http://stackoverflow.com/a/13506187/555798 – MikeTeeVee

2

Aquí hay una variación en la respuesta aceptada que era el más útil para mí:

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 

Las modificaciones mostrar el último tiempo de ejecución e incluyen el esquema del procedimiento.

0

Por alguna razón, mi vista dm_exec_procedure_stats se borra a sí misma durante el día. Así que solo lo ejecuté en este momento y los primeros tiempos de ejecución son de esta mañana, pero sé que no reiniciamos SQL esta mañana ni nada.

De todos modos, quería crear un programa que pudiera poner en un trabajo para ejecutar cada hora y capturar qué procesos se habían ejecutado recientemente. Esto es lo que hice:

Creé una tabla para registrar los procesos que se ejecutan y sus tiempos de ejecución primero y último.

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

creó un procedimiento que inserta o actualiza la tabla ProcsThatExecute. Ejecute esto cada hora en un trabajo y después de unos días, semanas o meses, tiene un registro de qué procesos se utilizan:

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 
Cuestiones relacionadas