Tần suất kích hoạt FOR MACHI TÌNH TRẠNG sẽ thực thi nếu hoạt động được gây ra bởi một ràng buộc FK với CẬP NHẬT CASCADE?


11

Tôi hiểu rằng một kích hoạt trên bảng t được xác định FOR EACH STATEMENTsẽ chạy một lần khi tôi thực thi UPDATE t ....

Bây giờ, khi tđược định nghĩa với FOREIGN KEY ... REFERENCES a ... ON UPDATE CASCADEvà tôi cập nhật N hàng vào a, điều đó sẽ khiến kích hoạt được gọi một lần hay N lần?

Đặt khác nhau, các thay đổi đối với một bảng được xếp tầng bởi một ràng buộc FK giống như một đơn hơn UPDATE, hoặc giống như một chuỗi các UPDATEs?


4
Bạn có thể tạo một trường hợp thử nghiệm! Chèn vào một bảng khác trong phần thân của trình kích hoạt và xem bạn nhận được bao nhiêu hàng. Sau đó viết nó lên trong câu trả lời của riêng bạn cho câu hỏi này (điều đó được cho phép, thậm chí được khuyến khích)!
Colin 't Hart

2
Các câu hàng đầu đề cập FOR EACH STATEMENTlà trực giao với phần còn lại của câu hỏi. Các ràng buộc FK được thực hiện với các kích hoạt đặc biệt FOR EACH ROW.
Erwin Brandstetter

1
@Erwin "CHO ​​MACHI ROW của một" hoặc "CHO ​​MACHI ROW của t"?
ypercubeᵀᴹ

@ypercube: Tôi đã thêm một câu trả lời với chi tiết.
Erwin Brandstetter

Câu trả lời:


6

Các ràng buộc khóa ngoại hiện đang được thực hiện với các kích hoạt nội bộ đặc biệt. Tất cả đều được chạy FOR EACH ROW.

Lưu ý rằng đây là những chi tiết triển khai có thể thay đổi, vì vậy đừng dựa vào nó. Nhưng những điều cơ bản không thay đổi trong vài phiên bản chính cuối cùng, vì vậy những thay đổi lớn là không thể.

Tôi đã chạy thử nghiệm nhanh với một ràng buộc FK đơn giản từ tblđến tbltype. Một FK đơn giản được triển khai với bốn kích hoạt bên trong đơn giản FOR EACH ROWtrong thử nghiệm của tôi trên trang 9,4.
Dưới đây là tóm tắt nhanh về cách điều tra:

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'

Hai kích hoạt "không hoạt động" nội bộ trên tbltype.
Hai kích hoạt "kiểm tra" nội bộ trên tbl.
Tất cả chúng đều được chạy FOR EACH ROW, như được chỉ định bởi các số lẻ trong tgtype.

2 byte của Postgres tgtype smallintđại diện cho một int16mã nguồn C trong đó mã hóa bit ít quan trọng nhất TRIGGER_TYPE_ROW. Giải thích chi tiết tại đây:

Bạn có thể dễ dàng kiểm tra điều này với một cặp kích hoạt giống hệt nhau mà bạn chỉ thay đổi FOR ROW/ STATEMENT...


5

Nó thực thi N lần và cách dễ nhất để thấy điều này là thực thi câu lệnh với một khoản dự phòng EXPLAIN ANALYZE, tức là

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

Điều này sẽ cung cấp cho bạn thông tin tương tự như thế này:

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

(đã thử nghiệm với 9.2)


1
Điều này có phần đáng ngạc nhiên đối với tôi. Đã thử nghiệm vào ngày 9,4 với kết quả tương tự.
dezso
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.