2012-05-02 13 views
17

Sto cercando di rintracciare tutte le stored procedure in un database che non è mai stato utilizzato o che non è stato utilizzato in molti mesi.Query TSQL per trovare stored procedure non utilizzate

Vorrei trovare una query per mostrare tutte le stored procedure che non sono in uso in modo che tali stored procedure possano essere analizzate per determinare se possono essere rimosse.

Ho familiarità con sys.procedures, ma non so come determinare se una procedura è in uso o meno.

SELECT * 
FROM sys.procedures; 

Utilizzo di SQL Server 2008 R2.

Aggiornamento Aggiornamento Aggiornamento

Utilizzando la query da Aaron Bertrand basso, leggermente modificato, questo è quello che ho finito per usare, ed è stato perfetto.

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; 

Grazie per il passaggio.

+0

spiacenti Siva, quello non è proprio quello che stavo cercando. La risposta sotto forma di Aaron lo ha fatto. –

risposta

26

DMV registreranno statistiche per le procedure, ma solo, eventualmente, andare il più lontano l'ultimo riavvio (e spesso non è così lontano, a seconda di quanto a lungo un piano vive 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; 

Quindi, se il tuo sistema è stato installato solo per un breve periodo, questa non è una misura affidabile. Il link @Siva sottolinea è utile anche per alcune altre idee. Purtroppo SQL Server in realtà non tenere traccia di questo per voi complessiva quindi a meno che si aggiunge tracciamento o l'accesso si è bloccato con la fiducia che riponete nel DMV ...

EDIT è stato un buon punto, stavo risolvendo per le procedure che hanno esecuzione. Invece si può decidere questo:

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; 

Oppure si può decidere di includere anche le procedure che hanno eseguito pure, ma l'ordine di loro da quando lo scorso correvano:

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; 

Questa ordinerà primi le procedure non sono stati eseguiti da un riavvio, quindi il resto quando sono stati eseguiti per ultimi, i primi per primi.

+0

Aaron, grazie. Quello che mi hai dato era molto vicino, con una piccola modifica ha fatto esattamente quello che stavo cercando. 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; –

+0

Sì, ho capito che questo è solo fino all'ultimo riavvio. Questo è molto buono per me. Grazie! –

+0

Vorrei ** non ** dire _ "questo è solo fino all'ultimo riavvio" _. Questo ** _ è _ ** cache dopo tutto e la cache è sempre in movimento (cose che vanno e cose che vanno fuori). Si prega di vedere la risposta di @ JeffModen qui: http://stackoverflow.com/a/13506187/555798 – MikeTeeVee

2

Ecco una variante la risposta accettata che è stato il più utile per me:

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 

Le modifiche visualizzano l'ultimo tempo di esecuzione e comprendono lo schema del procedimento.

0

Per qualche motivo, la mia vista dm_exec_procedure_stats si cancella da sola durante il giorno. Quindi l'ho appena eseguito in questo momento e i primi tempi di esecuzione sono da questa mattina, ma so che non abbiamo riavviato SQL stamattina o altro.

In ogni caso, volevo creare un processo che potessi inserire in un lavoro da eseguire ogni ora e acquisire i processi eseguiti di recente. Ecco cosa ho fatto:

Creata una tabella per registrare i proc eseguiti e i loro primi e ultimi tempi di esecuzione.

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

Creata una procedura che inserisce o aggiorna la tabella ProcsThatExecute. Eseguire questo ogni ora in un lavoro e dopo pochi giorni o settimane o mesi si ha un registro di cui proc abituarsi:

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 
Problemi correlati