内部アプリケーションが何年にもわたって進化するにつれ、人々はもはや関連性がなく、選別したいと考えているテーブルがいくつかあることがときどきあります。 SQL環境内、およびSSISなどのデータベースの依存関係を特定するための実用的な方法は何ですか?
私はかなり残忍なオプションが取られている場所で働いてきました:
SQL Serverにはそのインスタンス内の依存関係を追跡するためのツールが付属していることを感謝しますが、異なるインスタンスにデータベースがある場合、これらのツールは苦労するようです。依存関係のクエリを簡単にするオプションはありますか。「この列はどこで使用されていますか?」 「このストアドプロシージャのこの他のサーバーでオーバー」または「このSSISパッケージでオーバー」などの回答で?
これを行う簡単な方法はありません。テーブルから選択した場合と同様に、トリガーは機能しません。トリガーは起動されません。これを行うために私が見つけた最良の方法は、開発者に彼らが使用するものを追跡させることです。何かがドロップされる場合は、すべての開発チームに確認し、全員がサインオフした後、オブジェクトの名前を変更してください。その後、1か月間何も壊れることなく、オブジェクトを安全にドロップできます。
したがって:
私が以前にやったことは、テーブルをテーブルをマスクするビューにして、ビューのパフォーマンスを低下させることです(クロスジョイン自体、個別)。実際には削除しませんが、クライアントのタイムアウトまたは苦情を生成します...
過去に使用した簡単な方法の1つは(実際にはテーブルのサイズ、インデックス数のパフォーマンスなどに依存します)、アクションがテーブルで実行されたときにタイムスタンプを記録するトリガーを追加することです。これはパフォーマンスの問題を引き起こす可能性があるので、注意して扱う必要があります。@@ IDENTITYを使用する古いコードを台無しにする可能性があるため、ロギングテーブルでIDフィールドを使用しないように注意してください。もちろん、アプリケーションの機能がしばらく使用されていないことを示すだけかもしれません。
データベースにヒットする可能性のあるすべてのコードがデータベースにない場合、つまりランダムなクライアントがデータベースにクエリを実行している場合、依存関係を追跡することは非常に困難です。
編集:テーブルにSELECTトリガーを設定できないという点に対処するために、テーブルにインデックスがあると想定して機能する別のオプションを次に示します(2008でのみテスト済み)。
SELECT
last_user_seek,
last_user_scan,
last_user_lookup,
last_user_update
FROM
sys.dm_db_index_usage_stats AS usage_stats
INNER JOIN
sys.tables AS tables ON tables.object_id = usage_stats.object_id
WHERE
database_id = DB_ID() AND
tables.name = 'mytable'
ただし、サーバーが再起動されたり、デタッチされたりすると、使用状況の統計テーブルはクリアされることに注意してください。したがって、データを収集するジョブを設定する必要があります。私が知っているちょっとしたハック。
過去に私が使用した1つの方法は、削除するテーブルの候補リストを作成し、それらの名前を変更して障害を探すことでした。
私がリストを確立した方法は:
現在のストアドプロシージャ、トリガー、関数で使用されていないテーブルを確認する
空のテーブル(ゼロレコード);
非参照テーブル(関係のないテーブル)。
dBサーバーの起動後に使用されていなかったテーブルを確認する(DMV)
テキストファイルでリストを作成した後、ローカルのマップされたバージョン管理フォルダーから.csファイル(.netプロジェクトのみを持っている)を解析し、それらのテーブルが.csファイルで使用されているかどうかを確認するバッチスクリプトを作成しました(起こらないはずですが、ちょっと..私は驚きました)。 「いいえ」の場合、それは明らかです。「はい」の場合、リストを作成し、開発者にそのモジュールがまだ使用されているかどうかを確認するよう依頼します。
要するに、以前の連中は正しかった。銀の弾丸はない。
依存関係の追跡に使用するさまざまなツールと手法があります。
使用統計を見て(つまり、SQLオブジェクトが最後に呼び出されたのはいつか)、以下のSQLを使用します。
SELECT
last_execution_time,
(SELECT TOP 1
SUBSTRING(s2.text,statement_start_offset / 2+1 ,
((CASE WHEN statement_end_offset = -1 THEN
(LEN(CONVERT(nvarchar(max),s2.text)) * 2)
ELSE statement_end_offset END) - statement_start_offset) / 2+1)
) AS sql_statement,
execution_count
FROM sys.dm_exec_query_stats AS s1
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2
WHERE
s2.text like '%[OBJECT NAME]%'
and last_execution_time > [DATE YOU CARE ABOUT]
ORDER BY last_execution_time desc
注:サーバーが再起動されたり、デタッチされたりすると、使用統計テーブルがクリアされます。そのため、データを収集するジョブを設定する必要があります。私が知っているちょっとしたハック。 (@Miles Dから)
私の会社で実装しているポリシーは、SQL Serverに関係するすべてのものを一元的にソース管理することです。
まだ設定していませんが、最終的には、特定のテーブルやsprocなどを検索するために使用できる、ある種のインデックス/中央検索メカニズムを実装したいと考えています。実際には、新しいSQL Serverショップ-FoxProから変換しています。したがって、古いSQLオブジェクトはまだそれほど問題ではありませんが、将来の計画を立てています。
名前の変更/追跡のアプローチで私が目にする問題は、毎年実行されないものもあり、毎年実行されないものがあるということです。人々があなたに書くように頼んで、それから数ヶ月または数年後に再び頼むさまざまなその場限りのことは言うまでもありません。
SQL参照からの処理は行いませんが、Redgateの SQL Dependency Tracker を確認することをお勧めします。それは素晴らしい視覚化ツールです。
これは本当にあなたの質問への答えではありませんが、私はそれが言及に値すると思います:これは、データベース外のすべてのシステムがビューとsprocs。検索可能な.sqlファイルにこれらのビルドスクリプトがあるため、特定のテーブルまたは列が外部で使用されているかどうかを簡単に確認できます。
もちろん、SSISは通常、テーブルに直接接続するので、これはおそらく現在のところあなたのニーズにはあまり役に立たないでしょう。しかし、開発者がデータベースに接続して、あなた(またはDBAとしての役割を果たしている人)が必要なビューとsprocを作成するのを待つ必要があることについて不満を言うときは、次のように伝えることができます。 mは、ビューとsprocへの変更を常に通知する義務があります。」そして、これらの特定の変更に対して回帰テストを実行するだけです。
数年前、私は同様のものをチェックするツールを構築しようとしました。 TL; DRの答えは、その時点で利用可能なリソースを使用することは不可能であることがわかったということです。
この列はどこで使用されますか?
この質問は、いくつかのクエリ、ビュー、およびストアドプロシージャがselect *
列が常駐するテーブルから。次に、それらの結果を使用するプログラムを確認する必要があります。そのため、C#、Delphi、Java、VB、=などのソースコードを読み取ることができるスキャナー/インデクサー/パーサーが必要です。 ASP(クラシック)など、その列へのすべての参照を探し出そうとします。次に、それらのプログラムを分析して、そのコードが呼び出されているかどうかを確認する必要があります。
次のTSQLを使用できますsys.dm_sql_referencing_entitiesまたはsys.sql_expression_dependencies
あるいは、SQL Negotiator Pro、Redgateなどのツールで、GUIを使用してこれを視覚的に生成できます。