收集所有使用过的SQL Server对象

时间:2017-09-22 17:50:16

标签: sql-server extended-events

我们有一个包含大约5000个对象的大型数据库(表,视图,sql函数,存储过程等)。这些物体的很大一部分不再使用 - 但没有人确切地知道哪些物体。因此,我们会在不知道某人是否还在使用它们的情况下继续维护这些旧对象。

我们希望使用扩展事件来跟踪实际使用的对象。基本上,每当访问数据库对象时,我们都使用以下查询来收集事件。事件存储在* .xel文件中。

CREATE EVENT SESSION {mySession} ON SERVER
            ADD EVENT sqlserver.lock_acquired (
                SET collect_database_name = (0)
                    ,collect_resource_description = (1)
                ACTION(sqlserver.client_hostname, sqlserver.client_app_name, collect_system_time, database_id)
                WHERE (
                    [package0].[equal_boolean]([sqlserver].[is_system], (0)) -- user SPID
                    AND [package0].[equal_uint64]([resource_type], (5)) -- OBJECT
                    AND [package0].[equal_uint64]([database_id], {dbId}) -- user database
                    AND [package0].[greater_than_equal_int64]([object_id], ({minimalUserObjectId})) -- user object
                    AND ([mode] = (1)-- SCH - S
                         OR [mode] = (6)-- IS
                         OR [mode] = (8)-- IX
                         OR [mode] = (3)-- S
                         OR [mode] = (5)-- X
                         )

                )
            )
            ADD TARGET [package0].event_file
            (
                SET filename='{xelFile}',
                    max_file_size=25,
                    max_rollover_files=5000
            )
            WITH (
                 MAX_MEMORY = 25 MB
                ,EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
                ,MAX_DISPATCH_LATENCY = {MaxDispatchLatency} SECONDS
                ,MEMORY_PARTITION_MODE = PER_NODE
                ,TRACK_CAUSALITY = OFF
                ,STARTUP_STATE = OFF
            );
然后我们写了一个单独的程序,它定期读取那些* .xel文件,聚合这些值并将它们存储在* .xlsx文件中。

这适用于原理。但是,在生产数据库中,收集了大量数据(* .xel文件大小将增加到每天大约300 GB!)。此外,SQL服务器似乎耗尽了大量资源来收集事件 - 通常,用户无法连接到数据库或无法运行非常简单的查询,因为它们会超时。

是否还有其他资源密集型的方法来收集数据库对象的使用数据?

2 个答案:

答案 0 :(得分:0)

如果您正在查看表定义是否已更改,请使用

SELECT * FROM sys.tables order by modify_date desc

如果表格中有任何数据更新

SELECT OBJECT_NAME(OBJECT_ID) AS DatabaseName, last_user_update,*
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID( 'AdventureWorks')
AND OBJECT_ID=OBJECT_ID('test')

- 查找未使用的存储过程

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT s.name, s.type_desc
FROM sys.procedures s
LEFT OUTER JOIN sys.dm_exec_procedure_stats d
        ON s.object_id = d.object_id
WHERE d.object_id IS NULL
ORDER BY s.name

如果SQL Server 2016则用于UDF

SELECT * FROM sys.dm_exec_function_stats 

答案 1 :(得分:0)

试试这个

SELECT 
  [schema] = s.name, 
  [object] = o.name,
  o.type_desc
FROM sys.objects AS o
INNER JOIN sys.schemas AS s
  ON o.[schema_id] = s.[schema_id]
WHERE o.[type] IN ('P','U');