2017-09-22 13 views
0

約5,000のオブジェクト(テーブル、ビュー、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のファイルに格納し、別のプログラムを書きました。

これはprinicpally働きます。しかし、本番データベースでは、膨大な量のデータが収集されています(* .xelファイルは1日あたり約300GBのサイズになります)。また、SQLサーバーはイベントを収集するために多くのリソースを消費しているようです。ユーザーはデータベースに接続できないか、タイムアウトが発生するため非常に単純なクエリを実行できません。

DBオブジェクトの使用状況データを収集するために、他のリソースをほとんど必要としませんか?場合

+1

を試してみてください。このタイプのものは、しばしば、「もはや使用されていない」物体を落としていく。あなたは1年に1回だけ実行されるか、あるいはその間にさらに長く実行されるプロセスがあることを覚えておく必要があります。あなたの現在は実行可能でなければならないようです。すでに有効であることがわかっているオブジェクトを削除し始めるには、フィルタリングを追加するだけです。あなたが知っているオブジェクトを追跡し続けることには意味がありません。 –

+0

オブジェクトを一度に1つずつドロップして、何かが壊れていると不平を言う人がいるかどうかを確認します。 –

+0

@SeanLangeはい私はこれを知っています。イベントのキャプチャを少なくとも1年間は実行する予定でした。 –

答えて

0

テーブル定義が変更された場合、あなたが探している場合は、任意のデータが表に

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') 

を更新した場合、その後の場合は

SELECT * FROM sys.tables order by modify_date desc 

を使用 - 未使用のストアドプロシージャを見つける

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サーバー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

これはちょうど私にいくつかのオブジェクトの名前ではなく、使い方の名前を与えます –

関連する問題