web-dev-qa-db-ja.com

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

内部アプリケーションが何年にもわたって進化するにつれ、人々はもはや関連性がなく、選別したいと考えているテーブルがいくつかあることがときどきあります。 SQL環境内、およびSSISなどのデータベースの依存関係を特定するための実用的な方法は何ですか?

私はかなり残忍なオプションが取られている場所で働いてきました:

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

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

37
Rowland Shaw

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

14
mrdenny
  1. Sys.sql_modules.definitionで使用するコードを検索:参照されていますか?その後...
  2. 権限を確認してください:どのクライアントコードで呼び出すことができますか?その後...
  3. プロファイラ

したがって:

  • 参照もアクセス権もないテーブルの場合、それは使用されていません。
  • 参照と一部の権限なしで、プロファイラーを実行して使用状況を確認します
  • 権限と参照なしで、使用状況のログを追加します

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

7
gbn

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

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

6
Miles D

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

私がリストを確立した方法は:

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

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

  3. 非参照テーブル(関係のないテーブル)。

  4. dBサーバーの起動後に使用されていなかったテーブルを確認する(DMV)

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

要するに、以前の連中は正しかった。銀の弾丸はない。

4
Marian

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

私が知っているツール:

  • SQL Server依存関係ビューア(ただし、テーブルを作成する前にテーブルを使用してspを作成した場合、問題が発生する可能性があります)
  • Redgate SQL Dependency Tracker (@Eric Humphreyの回答による)
  • Resharper (呼び出しパスの確認に使用できる.netツール、Ithinkこれを使用して、主要な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経由で)開発者とコードの使用を確認する
  • オブジェクトの名前を変更し(つまり、post/prefix with _toBeDropped)、エラーを監視します
  • 権限を変更し、エラーを監視する
  • オブジェクトをドロップして祈る
3

私の会社で実装しているポリシーは、SQL Serverに関係するすべてのものを一元的にソース管理することです。

  • asp.netプロジェクト
  • SSRSプロジェクト
  • SSISプロジェクト
  • すべてのデータベースオブジェクトをスクリプトで並べ替え、リポジトリに格納することさえします。

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

名前の変更/追跡のアプローチで私が目にする問題は、毎年実行されないものもあり、毎年実行されないものがあるということです。人々があなたに書くように頼んで、それから数ヶ月または数年後に再び頼むさまざまなその場限りのことは言うまでもありません。

3

SQL参照からの処理は行いませんが、Redgateの SQL Dependency Tracker を確認することをお勧めします。それは素晴らしい視覚化ツールです。

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

もちろん、SSISは通常、テーブルに直接接続するので、これはおそらく現在のところあなたのニーズにはあまり役に立たないでしょう。しかし、開発者がデータベースに接続して、あなた(またはDBAとしての役割を果たしている人)が必要なビューとsprocを作成するのを待つ必要があることについて不満を言うときは、次のように伝えることができます。 mは、ビューとsprocへの変更を常に通知する義務があります。」そして、これらの特定の変更に対して回帰テストを実行するだけです。

2

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

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

この質問は、いくつかのクエリ、ビュー、およびストアドプロシージャがselect *列が常駐するテーブルから。次に、それらの結果を使用するプログラムを確認する必要があります。そのため、C#、Delphi、Java、VB、=などのソースコードを読み取ることができるスキャナー/インデクサー/パーサーが必要です。 ASP(クラシック)など、その列へのすべての参照を探し出そうとします。次に、それらのプログラムを分析して、そのコードが呼び出されているかどうかを確認する必要があります。

2
Tangurena

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

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

0
Jenny T