UPDATE CASCADE의 FK 제약 조건으로 작업이 발생하는 경우 FOR EACH STATEMENT 트리거가 얼마나 자주 실행됩니까?


11

로 정의 된 테이블 t의 트리거 FOR EACH STATEMENT가를 실행하면 한 번 실행 된다는 것을 이해 합니다 UPDATE t ....

이제 t로 정의되어 FOREIGN KEY ... REFERENCES a ... ON UPDATE CASCADE있고에서 N 행을 업데이트 a하면 트리거가 한 번 또는 N 번 호출됩니까?

달리 말하면, FK 제약 조건에 의해 테이블에 대한 변경 사항이 단일 UPDATE또는 일련의 UPDATEs 와 유사 합니까?


4
테스트 케이스를 만들 수 있습니다! 트리거 본문의 다른 테이블에 삽입하고 얻는 행 수를 확인하십시오. 그런 다음이 질문에 대한 자신의 답변으로 작성하십시오 (허용되며 권장됩니다)!
Colin 't Hart

2
가장 앞선 문장 FOR EACH STATEMENT은 나머지 질문과 직교합니다. FK 제약 조건은 특수 트리거로 구현됩니다 FOR EACH ROW.
Erwin Brandstetter

1
@Erwin "a의 각 행"또는 "t의 각 행"?
ypercubeᵀᴹ

@ ypercube : 세부 사항이있는 답변을 추가했습니다.
Erwin Brandstetter

답변:


6

외래 키 제약 조건은 현재 특수 내부 트리거로 구현됩니다. 그들 모두가 실행 FOR EACH ROW됩니다.

이것들은 변경 될 수있는 구현 세부 사항이므로, 그것에 의존하지 마십시오. 그러나 마지막 몇 가지 주요 버전에서는 기본 사항이 변경되지 않았으므로 주요 변경 사항이 거의 없습니다.

나는에서 간단한 FK 제약 조건과 빠른 테스트 실행 tbl에를 tbltype. FOR EACH ROWpg 9.4 테스트에서 간단한 FK가 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 개의 내부 "동작 없음"트리거가 tbltype있습니다.
에 두 개의 내부 "체크"트리거가 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 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.