Sql*_*yan 58 sql-server database-design clustered-index sql-server-2008
我有一个包含数百个表的非常大的数据库,经过许多产品升级后,我确信其中一半不再使用了.如何判断是否正在从中选择一个表?我不能只使用Profiler - 我不仅要观看超过几天,而且还有数千个存储过程,并且探查器不会将SP调用转换为表访问调用.
我唯一能想到的是在感兴趣的表上创建聚簇索引,然后监视sys.dm_db_index_usage_stats聚类索引是否有任何搜索或扫描,这意味着表中的数据已加载.但是,在每个表上添加聚簇索引是一个坏主意(由于许多原因),因为这是不可行的.
我还有其他选择吗?我一直想要一个像"SELECT触发器"这样的功能,但是可能还有其他原因导致SQL Server没有这个功能.
解:
谢谢,Remus,指出我正确的方向.使用这些列,我创建了以下SELECT,它完全符合我的要求.
WITH LastActivity (ObjectID, LastAction) AS
(
SELECT object_id AS TableName,
last_user_seek as LastAction
FROM sys.dm_db_index_usage_stats u
WHERE database_id = db_id(db_name())
UNION
SELECT object_id AS TableName,
last_user_scan as LastAction
FROM sys.dm_db_index_usage_stats u
WHERE database_id = db_id(db_name())
UNION
SELECT object_id AS TableName,
last_user_lookup as LastAction
FROM sys.dm_db_index_usage_stats u
WHERE database_id = db_id(db_name())
)
SELECT OBJECT_NAME(so.object_id) AS TableName,
MAX(la.LastAction) as LastSelect
FROM sys.objects so
LEFT
JOIN LastActivity la
on so.object_id = la.ObjectID
WHERE so.type = 'U'
AND so.object_id > 100
GROUP BY OBJECT_NAME(so.object_id)
ORDER BY OBJECT_NAME(so.object_id)
Run Code Online (Sandbox Code Playgroud)
Rem*_*anu 42
查看sys.dm_db_index_usage_stats.last_user_xxx列将包含从用户请求访问表的最后时间.此表在服务器重新启动后重置其跟踪,因此您必须在依赖其数据之前保持运行一段时间.
Re:Profiler,如果您监视SP:StmtCompleted,它将捕获在存储过程中执行的所有语句,以便捕获sproc中的表访问.如果不是所有内容都通过存储过程,您可能还需要SQL:StmtCompleted事件.
将会有大量事件,因此由于跟踪的大小,长时间跟踪可能仍然不实用.但是,您可以应用过滤器 - 例如,TextData包含您要检查的表的名称.您可以在任何时候提供要过滤的表名列表,并逐步完成它们.因此,如果没有访问过这些表,则不应该获取任何跟踪事件.
即使你认为这对你来说不合适/可行,我认为值得继续扩展.
另一种解决方案是对源代码进行全局搜索,以查找对表的引用.您可以查询存储过程定义以检查给定表的匹配项,或者只生成完整的数据库脚本并对表名执行查找.
| 归档时间: |
|
| 查看次数: |
61008 次 |
| 最近记录: |