UPDATE CASCADEを使用したFK制約によって操作が発生した場合、FOR EACH STATEMENTトリガーはどのくらいの頻度で実行されますか?


11

で定義されたテーブルtのトリガーは、FOR EACH STATEMENTを実行すると1回実行されることを理解していますUPDATE t ...

では、をtで定義しFOREIGN KEY ... REFERENCES a ... ON UPDATE CASCADE、でN行を更新aすると、トリガーが1回呼び出されるのですか、それともN回呼び出されるのですか?

別の言い方をすると、FK制約によってカスケードされたテーブルへの変更は、単一のUPDATE、または一連のUPDATEのようなものですか?


4
テストケースを作成できます。トリガー本体の別のテーブルに挿入して、取得される行数を確認します。次に、この質問に対する独自の回答にそれを書いてください(それは許可され、奨励されています)!
Colin 't Hart

2
言及する最初の文FOR EACH STATEMENTは、残りの質問と直交しています。FK制約は、特別なトリガーで実装されますFOR EACH ROW
Erwin Brandstetter、2015年

1
@アーウィン「FOR EACH ROW of a」または「FOR EACH ROW of t」?
ypercubeᵀᴹ

@ypercube:詳細を含む回答を追加しました。
Erwin Brandstetter、2015年

回答:


6

外部キー制約は現在、特別な内部トリガーで実装されています。それらのすべてが実行されFOR EACH ROWます。

これらは変更される可能性のある実装の詳細であるため、それに依存しないでください。しかし、基本は最近のいくつかのメジャーバージョンで変更されていないため、メジャーな変更はほとんどありません。

からtblまでの単純なFK制約を使用して簡単なテストを実行しましたtbltype。単純なFKはFOR EACH ROW、pg 9.4のテストで4つの単純な内部トリガーを使用して実装されています。
調査方法の簡単な概要は次のとおりです。

SELECT oid  -- 74791
FROM   pg_constraint
WHERE  conrelid = 'tbl'::regclass
AND    contype = 'f';

SELECT objid, classid::regclass  -- 74792,74793,74794,74795 / 'pg_trigger'
FROM   pg_depend
WHERE  refobjid = 74791
AND   deptype = 'i'

SELECT tgrelid::regclass, tgname, tgfoid, tgtype FROM pg_trigger
WHERE  oid IN (74792,74793,74794,74795) ORDER BY tgfoid;

'tbl'    ;'RI_ConstraintTrigger_c_74794';1644;5
'tbl'    ;'RI_ConstraintTrigger_c_74795';1645;17
'tbltype';'RI_ConstraintTrigger_a_74792';1654;9
'tbltype';'RI_ConstraintTrigger_a_74793';1655;17

SELECT oid, proname FROM pg_proc
WHERE oid IN (1654,1655,1644,1645);

1644;'RI_FKey_check_ins'
1645;'RI_FKey_check_upd'
1654;'RI_FKey_noaction_del'
1655;'RI_FKey_noaction_upd'

の2つの内部「noaction」トリガーtbltype
の2つの内部「チェック」トリガーtbl
FOR EACH ROW奇数で示されているように、それらすべてが実行されますtgtype

Postgresの2バイトは、最下位ビットがエンコードするCのソースコードをtgtype smallint表します。詳細な説明はこちら:int16TRIGGER_TYPE_ROW

変更するだけで、同じトリガーのペアでこれを簡単にテストできますFOR ROW/ STATEMENT...


5

これはN回実行されます。これを確認する最も簡単な方法は、ステートメントをEXPLAIN ANALYZE前に追加して実行することです。

EXPLAIN ANALYZE UPDATE a SET col = 1 WHERE othercol = 'foo';

これにより、次のような情報が得られます。

Trigger for constraint t_col_fk on a: time=1.300 calls=9

(9.2でテスト済み)


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