2

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

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

create trigger ステートメント自体に問題があるとは思いません。create trigger ステートメントは、テスト環境で迅速に成功し、行がテーブルに挿入/更新されたときにトリガーが正しく機能しました。テスト データベースでトリガーを作成したとき、テーブルには負荷がなく、行数がかなり少なかったため、ライブ/運用データベースとは異なります (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 では、トリガーはデフォルトで有効に作成されます。デフォルトで無効になっているトリガーを作成することはできますか?

他のアイデアはありますか?

4

5 に答える 5

6

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

sp_who を使用してブロックの送信元を見つけ、そこから調査します。

于 2008-10-23T19:52:47.133 に答える
4

CREATE Trigger がテーブル全体にロックをかけようとするだろうと思います。

そのテーブルで多くのアクティビティがある場合、長時間待機する必要があり、デッドロックが発生する可能性があります。

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

とはいえ、アクティブな接続に「小さな」変更を加えるのは魅力的です。ロックの競合がどこにあるかを確認するには、ロック/接続を確認する必要があります。

于 2008-10-23T17:52:09.140 に答える
2

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

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

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

私の友人である Dennis がこの記事を書いており、大量の情報があるときに少量の情報をテストすると、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

于 2009-06-02T13:40:56.077 に答える
2

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

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

于 2008-10-23T17:50:42.450 に答える
0

トリガーを変更する前に実行DISABLE TRIGGER triggername ON tablenameしてから、トリガーを再度有効にしますENABLE TRIGGER triggername ON tablename

于 2016-06-01T11:14:11.320 に答える