识别未使用的存储过程

Que*_*CPO 25 sql-server profiler

明年,我将帮助清理多个 SQL Server 环境。

我们有大约 10,000 个存储过程,估计其中只有大约 1000 个是定期使用的,另外还有 200 个左右是在极少数情况下使用的,这意味着我们有很多工作要做。

由于我们有多个部门和团队可以访问这些数据库和程序,因此我们并不总是调用这些程序的人,这意味着我们必须确定正在调用哪些程序。最重要的是,我们希望在几个月内而不是几天内确定这一点(这消除了一些可能性)。

一种方法是使用SQL Server Profiler并跟踪正在调用的过程,并将它们与我们拥有的过程列表进行比较,同时标记是否使用了这些过程。从那时起,我们可以将程序移动到不同的模式,以防部门尖叫。

Profiler在这里使用最有效的方法吗?和/或你们中有没有人做过类似的事情并找到了另一种方法/更好的方法来做到这一点?

Kin*_*hah 33

您可以 在测试或业务周期期间使用服务器端跟踪(与使用会产生更多资源的 Profiler GUI 不同)并仅捕获与 SP 相关的内容。然后您可以将其加载到表格或 excel 中以进行进一步分析。

第二种方法,是使用DMV sys.dm_exec_procedure_stats(有限制,如果重新启动sql server,然后刷新数据)。

您甚至可以安排一个作业来将 DMV 数据捕获到一个表中以保持它的持久性。

 -- Get list of possibly unused SPs (SQL 2008 only)
    SELECT p.name AS 'SP Name'        -- Get list of all SPs in the current database
    FROM sys.procedures AS p
    WHERE p.is_ms_shipped = 0

    EXCEPT

    SELECT p.name AS 'SP Name'        -- Get list of all SPs from the current database 
    FROM sys.procedures AS p          -- that are in the procedure cache
    INNER JOIN sys.dm_exec_procedure_stats AS qs
    ON p.object_id = qs.object_id
    WHERE p.is_ms_shipped = 0;
Run Code Online (Sandbox Code Playgroud)

参考:

  • 确保您在数周甚至数月内定期检查 DMV,因为可能存在仅每月甚至每季度运行一次的 SP。当实例重新启动、手动清除或什至随着时间的推移,DMV 会被清除。 (2认同)

小智 11

您会发现这个问题很有用,它适用于表和列,但建议使用第三方工具 ApexSQL Clean,它也可以找到未使用的存储过程以及数据库或外部数据库中任何其他对象未引用的所有对象

免责声明:我作为支持工程师为 ApexSQL 工作

  • OP 不想找到“未引用的存储过程”,而是想找到未使用的 SP。你的回答不能作为这个问题的答案。 (3认同)

Mar*_*ith 10

如果您使用的是 SQL Server 2008+,您还可以使用带有直方图目标的扩展事件。可能这比痕迹更轻。

AFAIK 您需要为每个感兴趣的数据库创建一个不同的会话,因为我看不到任何迹象表明可以对多个列进行分桶。下面的快速示例过滤了database_id=10

CREATE EVENT SESSION [count_module_start_database_10]
ON SERVER
ADD EVENT sqlserver.module_start
(  
        WHERE (source_database_id=10) 
)
ADD TARGET package0.asynchronous_bucketizer
(     SET  filtering_event_name='sqlserver.module_start', 
            source_type=0, 
            source='object_id',
            slots = 10000
)
WITH (MAX_DISPATCH_LATENCY = 5 SECONDS)
GO
ALTER EVENT SESSION [count_module_start_database_10]
ON SERVER
STATE=START
Run Code Online (Sandbox Code Playgroud)

然后在该数据库中运行一些存储过程几次并检索数据后

SELECT CAST(target_data as XML) target_data
FROM sys.dm_xe_sessions AS s 
JOIN sys.dm_xe_session_targets t
    ON s.address = t.event_session_address
WHERE s.name = 'count_module_start_database_10'
Run Code Online (Sandbox Code Playgroud)

输出是

CREATE EVENT SESSION [count_module_start_database_10]
ON SERVER
ADD EVENT sqlserver.module_start
(  
        WHERE (source_database_id=10) 
)
ADD TARGET package0.asynchronous_bucketizer
(     SET  filtering_event_name='sqlserver.module_start', 
            source_type=0, 
            source='object_id',
            slots = 10000
)
WITH (MAX_DISPATCH_LATENCY = 5 SECONDS)
GO
ALTER EVENT SESSION [count_module_start_database_10]
ON SERVER
STATE=START
Run Code Online (Sandbox Code Playgroud)

例如,显示带有object_idof的过程1287675635执行了 36 次。的asynchronous_bucketizer不仅是记忆,因此最好的办法是设立一些调查这个每隔一段时间,并保存到永久存储。