質問

ライブ/本番データベースで、テーブルにトリガーを追加しようとしていますが、失敗しました。何度か試してみましたが、トリガーの作成ステートメントが完了するまでに30分以上かかり、キャンセルしました。

テーブルは、いくつかの異なるプロセスによって頻繁に読み書きされるテーブルです。テーブルを更新するスケジュールされたジョブを無効にし、テーブルのアクティビティが少ないときに試行しましたが、テーブルにアクセスするすべてを停止することはできません。

トリガーの作成ステートメント自体に問題があるとは思わない。トリガーの作成ステートメントは、テスト環境で正常かつ迅速に実行され、テーブルに行が挿入/更新されたときにトリガーが正しく機能します。テストデータベースでトリガーを作成したときは、テーブルに負荷がなく、行数がかなり少なくなりました。これは、ライブ/実稼働データベースとは異なります(100対13,000,000 +)。

これは、実行しようとしているトリガーの作成ステートメントです

CREATE TRIGGER [OnItem_Updated] 
    ON  [Item]
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    IF update(State)
    BEGIN
        /* do some stuff including for each row updated call a stored 
          procedure that increments a value in table based on the 
          UserId of the updated row */
    END
END

行の更新中、または行が多数ある場合、テーブルでトリガーを作成する際に問題が発生する可能性はありますか?

SQLServerでは、トリガーはデフォルトで有効に作成されます。デフォルトで無効化されたトリガーを作成することは可能ですか?

その他のアイデア?

役に立ちましたか?

解決

問題はテーブル自体にあるのではなく、トリガーを作成するために更新する必要があるシステムテーブルにある可能性があります。通常のプロセスの一部として他の種類のDDLを実行している場合、彼らはそれを保持している可能性があります。

sp_whoを使用して、ブロックがどこから来ているかを調べ、そこから調査します。

他のヒント

CREATE Triggerはテーブル全体にロックをかけようとするでしょう。

そのテーブルで多くのアクティビティがある場合、長時間待たなければならず、デッドロックが発生する可能性があります。

スキーマを変更する場合は、データベースの全員を実際に取得する必要があります。

「小」を入れるのは魅力的だと言っていましたが、アクティブな接続によって変化します。ロックの競合がどこにあるかを確認するには、ロック/接続を確認する必要があります。

それは奇妙です。 AFTER UPDATE トリガーは、テーブル内の既存の行をチェックする必要はありません。テーブルのロックを取得してトリガーを追加できない可能性があると思います。

基本的には何もしないトリガーを作成してみてください。作成できない場合は、ロックの問題です。可能であれば、そのトリガーを無効にし、目的のコードを本文に追加して有効にすることができます。 (作成中にトリガーを無効にできるとは思わない。)

問題の一部は、トリガー自体の場合もあります。トリガーが誤ってテーブルのすべての行を更新していませんか?テストデータベースの100行と13,000,000行の間には大きな違いがあります。パフォーマンスを予測する方法がないほど大きなデータセットがある場合、このような小さなセットに対してコードを開発することは非常に悪い考えです。 100レコードで正常に動作するSQLは、数百万のシステムを数時間にわたって完全にロックする可能性があります。 prodに昇格するときではなく、devでそれを本当に知りたいです。

トリガーでストアドプロシージャを呼び出すことは、通常非常に悪い選択です。また、トリガーでさらに悪い選択であるレコードをループする必要があることも意味します。トリガーは、複数のレコードの挿入/更新または削除のアカウントを無効にする必要があります。誰かが100,000行を挿入すると(13,000,000レコードがある場合はそうではありません)、レコードベースのストアドプロシージャをループすると数時間かかり、テーブル全体をロックし、すべてのユーザーが開発者を追い詰めて殺す(または少なくともmaim)彼は仕事を終わらせることができないからです。

prodと同じサイズのレコードセットに対してテストするまで、このトリガーをprodに配置することすら考えません。

友人のデニスは、大量の情報があるときに少量の情報をテストすると、devで気付かなかったprdで問題が発生する理由を説明するこの記事を書きました。 http://blogs.lessthandot.com/index.php/DataMgmt/?blog=3&title=your-testbed-has-to-have-the-same-volume& disp = single& more = 1& c = 1& tb = 1& pb = 1#c1210

トリガーを変更する前に DISABLE TRIGGER triggername ON tablename を実行し、 ENABLE TRIGGER triggername ON tablename

で再度有効にします
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top