データベースの依存関係を追跡するにはどうすればよいですか?


37

内部アプリケーションが数年にわたって進化するにつれて、人々はもはや関連性がなくなったと考え、カリングしたいと考えているテーブルがいくつかあることに気付くでしょう。SQL環境内で、そしておそらくSSISのようなものに進むために、データベースの依存関係を識別するための実用的な方法は何ですか?

私は次のようなかなり残忍な選択肢が取られている場所で働いてきました:

  • 最初にドロップし、後で質問します(存在しないテーブルを抽出しようとすると、データウェアハウスのビルドを強制終了できます)
  • 最初に権限を削除し、エラーが報告されるまで待機します(障害が正しく処理されない場合、サイレントバグが発生する可能性があります)

SQL Serverには、そのインスタンス内の依存関係を追跡するツールが付属していることを感謝していますが、異なるインスタンスにデータベースがある場合、これらは苦労しているようです。「この列はどこで使用されますか?」などの質問に答えるなど、依存関係の照会を簡単にするオプションがありますか?「このストアドプロシージャのこの他のサーバーでオーバー」または「このSSISパッケージでオーバー」などの回答がありますか?

回答:


14

これを行う簡単な方法はありません。トリガーは機能しません。テーブルから選択した場合、トリガーは起動されません。これを実現するために私が見つけた最善の方法は、開発者に使用内容を追跡させることです。何かがドロップされる場合は、すべての開発チームに確認し、全員がサインオフした後、オブジェクトの名前を変更します。その後、1か月間または何も中断しない場合、オブジェクトを安全にドロップできます。


7
  1. sys.sql_modules.definitionで使用法の検索コード:参照されていますか?その後...
  2. アクセス許可を確認します:どのクライアントコードがそれを呼び出すことができますか?その後...
  3. プロファイラー

したがって:

  • 参照も権限もないテーブルの場合、使用されていません。
  • 参照なしでいくつかの権限がある場合、プロファイラーを実行して使用状況を確認します
  • 権限と参照なしで、使用状況のログを追加します

以前に行ったことは、テーブルをテーブルをマスクするビューにしてから、ビューのパフォーマンスを低下させることです(クロスジョイン自体、異なる)。実際には削除しませんが、クライアントのタイムアウトまたは苦情を生成します...


6

私が過去に使用した簡単な方法の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' 

ただし、サーバーの再起動時、デタッチ時などに使用統計テーブルがクリアされることに注意してください。したがって、データを収集するジョブを設定する必要があります。私が知っているハックのビット。


4

過去に使用した1つの方法は、テーブルの候補リストを作成して削除し、それらの名前を変更してエラーを探すことでした。

リストの作成方法は次のとおりです。

  1. 現在のストアドプロシージャ、トリガー、関数で使用されていないテーブルを確認する

  2. 空のテーブル(ゼロレコード);

  3. 非参照テーブル(リレーションシップを持たないテーブル);

  4. DBサーバーが起動してから使用されていないテーブルを確認します(DMV)

リストをテキストファイルに作成した後、ローカルにマップされたバージョン管理フォルダーから.csファイル(.netプロジェクトのみ)を解析し、それらのテーブルが.csファイルで使用されているかどうかを確認するバッチスクリプトを作成しました(起こるべきではありませんが、ちょっと..私は驚きました。「いいえ」の場合、それは明らかです。「はい」の場合、リストを作成し、そのモジュールがまだ使用されているかどうかを開発者に確認します。

つまり、要するに、以前の人たちは正しいです。特効薬はありません。


3

私の会社で実装しているポリシーは、SQL Serverに関係するすべてのものをソース管理下に置き、中央の場所に置くことです。

  • asp.netプロジェクト
  • SSRSプロジェクト
  • SSISプロジェクト
  • さらに、すべてのデータベースオブジェクトをスクリプト化して、一種のリポジトリに格納します。

まだ設定していませんが、最終的には特定のテーブルやsprocなどを検索するために使用できる何らかのインデックス/中央検索メカニズムを実装したいと考えています。 。したがって、古いSQLオブジェクトはまだあまり問題ではありませんが、将来的には計画しています。

名前の変更/トレースのアプローチで見られる問題は、毎年実行されるのではなく、毎年実行されるものがあることです。人々が書くようにあなたに頼み、それから数ヶ月または数年後に再び頼む様々なアドホックな事は言うまでもありません。


3

依存関係の追跡に使用するさまざまなツールとテクニックがあります。

私が知っているツール:

  • SQL Server Dependency Viewer(ただし、テーブルを使用するspがテーブルの作成前に作成された場合は問題が発生する可能性があります)
  • Redgate SQL Dependency Tracker(@Eric Humphreyの回答経由)
  • Resharper(呼び出しパスを調べるために使用できる.netツール。主要なSQL呼び出しが使用されている場所を追跡するために使用できると思います

方法

  • コードはSQLオブジェクトの使用を検索します(ただし、上記のツールの一部を複製します)
  • 使用統計(つまり、いつ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から)

テクニック

  • 最後の使用状況を検索します(上記の使用状況の統計を参照)
  • 使用場所を検索します(ツールを参照)
  • 開発者とコードの使用を確認する(@MrDenny経由)
  • オブジェクトの名前を変更し(例:_toBeDroppedでpost / prefix)、エラーを監視します
  • アクセス許可を変更し、エラーを監視する
  • オブジェクトをドロップして祈る

2

数年前、私は同様のものをチェックするツールを構築しようとしました。TL; DRの答えは、その時点で利用可能なリソースを使用することは不可能だとわかったということです。

この列はどこで使用されますか?

この質問はselect *、列が存在するテーブルから多くのクエリ、ビュー、およびストアドプロシージャが使用することを認識すると、より複雑になります。次に、それらの結果を使用するプログラムを調べる必要があります。 C#、Delphi、Java、VB、ASP(クラシック)などのソースコードを読み取ることができ、その列へのすべての参照を追い詰めようとします。次に、これらのプログラムを分析して、そのコードがもう呼び出されているかどうかを確認する必要があります。



2

これは実際にはあなたの質問への答えではありませんが、言及する必要があると思います。これは、データベース外のすべてのシステムがビューとsprocsを介して通信する必要がある理由の1つです。これらのビルドスクリプトは検索可能な.sqlファイルにあるため、特定のテーブルまたは列が外部で使用されているかどうかを簡単に確認できます。

もちろん、SSISは通常、テーブルに直接接続するため、これはおそらく現時点でのニーズにはあまり役立ちません。しかし、開発者がデータベースに接続し、あなた(またはDBAとしてサービスを提供している人)が必要なビューやsprocを作成するのを待つ必要があると不平を言うときは、「テーブルまたは列は削除または名前変更される可能性があります。 mは、ビューとsprocの変更を常に通知する義務があります。」そして、これらの特定の変更に対して回帰テストを行うだけです。


0

次のTSQLを使用できますsys.dm_sql_referencing_entitiesまたはsys.sql_expression_dependencies

あるいは、SQL Negotiator Pro、Redgateなどのツールは、GUIを使用して視覚的に生成できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.