MSSQL数据库清理 - 如何找到未使用的对象(表,视图,过程,函数)

Bud*_*Joe 8 sql-server logging

假设您已经继承了MS SQL 2000或2005数据库,并且您知道某些表,视图,过程和函数实际上并未在最终产品中使用.

是否有某种内部日志记录或其他机制可以告诉我哪些对象没有被调用?或者只被称为几次而不是数千次.

Tim*_*mbo 5

答案将在一定程度上取决于数据库是如何组合在一起的,但我解决类似问题的方法有 3 个方面:

找出哪些对象没有内部依赖关系。您可以通过对 sysdepends 的查询来解决这个问题,例如:

select 
    id, 
    name
from
    sys.sysdepends sd
inner join sys.sysobjects so
    on so.id = sd.id
where 
    not exists (
        select 
            1
        from 
            sysdepends sd2
        where 
            sd2.depid = so.id
    )
Run Code Online (Sandbox Code Playgroud)

您应该将此与收集对象类型 (sysobjects.xtype) 结合起来,因为您只想隔离表、函数、存储过程和视图。还要忽略以“sp_”开头的任何过程,除非有人为您的应用程序创建了具有这些名称的过程!

许多返回的过程可能是您的应用程序的入口点。也就是说,从您的应用程序层或其他远程调用调用的过程,并且在数据库中没有任何依赖于它们的对象。

假设该过程不会太具有侵入性(它会产生一些额外的负载,但不会太多),您现在可以打开 SP:Starting、SQL:BatchStarting 和/或 SP:StmtStarting 事件的一些分析。只要你认为合适就运行它,最好登录到一个 sql 表以便于交叉引用。您应该能够消除许多直接从您的应用程序调用的过程。

通过交叉引用来自该日志的文本数据和您的依赖对象列表,您有望隔离大部分未使用的过程。

最后,您可能希望获取由此过程产生的候选列表,并针对它们 grep 您的源代码库。这是一项繁琐的任务,仅仅因为您在代码中找到引用并不意味着您需要它们!可能只是代码尚未删除,尽管它现在在逻辑上无法访问。

这远非一个完美的过程。一个相对干净的替代方法是在服务器上设置更详细(因此具有侵入性)的分析以监视所有活动。这可以包括在日志处于活动状态期间调用的每个 SQL 语句。然后,您可以从该文本数据重新处理依赖表,甚至跨数据库依赖关系。我发现日志细节的可靠性(每秒尝试解析的行数太多)和难以处理的绝对数量的数据。如果您的应用程序不太可能受到这种影响,那么这可能是一个很好的方法。

警告:

因为,据我所知,没有一个完美的答案,特别是要小心删除表格。如果出现问题,可以轻松替换过程、函数和视图(当然,在刻录它们之前,请确保将它们置于源代码管理中!)。如果您感到非常紧张,为什么不重命名表并使用旧名称创建视图,那么您就可以轻松解决了。