2017-09-22 64 views
0

我們擁有一個大型數據庫,包含大約5000個對象(表,視圖,sql函數,存儲過程等)。這些物體中的很大一部分不再被使用 - 但沒人確切知道哪些物體。所以我們不知道是否有人仍然使用這些舊對象。收集所有使用的SQL Server對象

我們希望使用擴展事件來跟蹤實際使用的對象。實質上,我們使用以下查詢來在訪問數據庫對象時收集事件。事件存儲在* .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文件,aggretates值並將它們存儲在一個* .xlsx文件。

這主要工作。但是,在生產數據庫中,收集的數據量非常大(* .xel文件的大小將增至每天大約300 GB!)。此外,SQL服務器似乎花費了大量資源來收集事件 - 通常,用戶無法連接到數據庫,或者無法運行非常簡單的查詢,因爲它們會超時。

是否有其他任何資源密集型的方式來收集db對象的使用數據?

+1

無論你選擇在這裏我要提醒你的解決方案。這種類型的東西通常會丟棄「不再使用」的對象。您需要記住,有些流程只能每年運行一次,有時甚至更長。似乎你目前的狀況應該是可行的。您只需添加一些過濾即可開始消除您已知的已知對象。在繼續追蹤你知道使用的物體方面沒有意義。 –

+0

一次只放一個物體,看是否有人打電話抱怨有什麼東西壞了。 –

+0

@SeanLange是的,我知道這一點。我們計劃讓事件捕獲運行至少一年。 –

回答

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 
+0

只有當表中的數據更新至少包含一個索引時,纔會更新dm_db_index_usage_stats? –

+0

dm_exec_procedure_stats文檔(https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-exec-procedure-stats-transact-sql)表示:只要過程不再位於查詢緩存中,統計數據就會被清除。當然,這並不意味着程序根本沒有被使用,只是在這個時候它沒有被正確使用。 –

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'); 
+0

這只是給我一些對象的名稱,而不是它們的用法 –