web-dev-qa-db-ja.com

データベースが使用されているかどうかを示すSQL Server DMV

データベースが利用されているか、アクセスされているかを確認するための最良の指標は何ですか?

I/O使用率に基づいてインデックス統計を試しましたが、どれも良い指標とは思えません。

問題:開発環境に多数のデータベースがあり、スペースの問題により、実際に必要なデータベースをいじる必要なしに、使用されていないデータベースを廃止しようとしています。

4
Viktoria Bakos

SQL Serverは、実際にはデータベースアクセスを希望どおりに追跡しません。少なくとも後方に移動します(サーバー側のトレース、拡張イベント、監査などを設定できます)。

使用できるボールパークは1つあります。インデックスの使用状況とプロシージャ/トリガー/クエリの統計を追跡するDMVです。例えば:

;WITH d AS
(
  SELECT d = database_id, name FROM sys.databases
  WHERE state = 0 AND database_id BETWEEN 5 AND 32766
),
index_usage(d,lsk,lsc,llk,lupd) AS
(
  SELECT database_id, MAX(last_user_seek), MAX(last_user_scan),
    MAX(last_user_lookup), MAX(last_user_update)
  FROM sys.dm_db_index_usage_stats
  WHERE database_id BETWEEN 5 AND 32766
  GROUP BY database_id
),
proc_stats(d,lproc) AS
(
  SELECT database_id, MAX(last_execution_time) 
    FROM sys.dm_exec_procedure_stats
    WHERE database_id BETWEEN 5 AND 32766
    GROUP BY database_id
),
trig_stats(d,ltrig) AS
(
  SELECT database_id, MAX(last_execution_time)
    FROM sys.dm_exec_trigger_stats
    WHERE database_id BETWEEN 5 AND 32766
    GROUP BY database_id
),
query_stats(d,lquery) AS
(
  SELECT t.[dbid], MAX(s.last_execution_time) 
    FROM sys.dm_exec_query_stats AS s
    CROSS APPLY sys.dm_exec_sql_text(s.plan_handle) AS t
    WHERE t.[dbid] BETWEEN 5 AND 32766
    GROUP BY t.[dbid]
)
SELECT d.name,i.lsk,i.lsc,i.llk,i.lupd,p.lproc,t.ltrig,q.lquery
FROM d LEFT OUTER JOIN index_usage AS i ON d.d = i.d
LEFT OUTER JOIN proc_stats  AS p ON d.d = p.d
LEFT OUTER JOIN trig_stats  AS t ON d.d = t.d
LEFT OUTER JOIN query_stats AS q ON d.d = q.d;

ストアドプロシージャがなく、sys.dm_exec_query_statsにあるクエリが複数のデータベースを参照している可能性があるため、これらの統計は完全に信頼できるわけではないことに注意してください。

また、SQL Serverの再起動時、データベースのデタッチ/アタッチまたは復元時、またはデータベースの自動クローズ時にリセットされ、場合によっては、キャッシュに残っているプラ​​ン(別のデータベースがその数分以内に完全に引き継ぎます)。したがって、過去を調べている場合、ビジネスサイクル全体でこれらのことが何も起こっていないことがわかっていない限り、データベースが使用されているかどうかを判断するためにこれらの数値だけに依存することはありません(データベースを削除するときにこれらの自動化されたプロセスが失敗することを気にしない場合でも、データベースは最新の状態に見えます)。

もう1つの注意点は、特定のインデックスアクセスがインデックス使用状況ビューで追跡されない可能性があることです。たとえば、メモリ最適化テーブルを追加するSQL Server 2014では、これらのハッシュインデックスに対するアクティビティはこのようにキャプチャされません(およびsys.dm_db_xtp_hash_index_statsなど、アクティビティがキャプチャされると思われるビューには日付が含まれていません/ time列)。 SQL Server 2014とインメモリOLTP( "Hekaton")を使用している場合は、それらのオブジェクトをカバーするための調査を追加する必要がある場合があります(オブジェクトがデータベース)。

そしてもう1つの注意点は、sys.dm_exec_query_statsによってキャプチャされたクエリが誤検知になる可能性があることです。たとえば、データベースにfilestream/filetableがある場合、システムによってこれらのクエリが時々実行されていることがわかります。

select table_id, item_guid, oplsn_fseqno, oplsn_bOffset, oplsn_slotid
from [database].[sys].[filetable_updates_<some_id>] with (readpast) order by table_id

したがって、上記のクエリに追加のフィルタリングを追加して、それらを除外することができます(必要なクエリを誤って除外しない限り)。これはおそらくその派生テーブルへの安全な追加です:

AND t.[text] NOT LIKE N'%oplsn_fseqno%'

結局のところ、開発環境で最も安全なことは、不明なデータベースを1週間オフラインにすることです。誰も不平を言わない場合、それらをバックアップし、それらを落としてください。誰かが行方不明になっていることに気づくまでに1週間以上かかる場合は、いつでも(そこにあるか、他の場所に)復元できます。

私はこれについても少しブログを書いています:

6
Aaron Bertrand