Operasyonun GÜNCELLEME KASKADI ile ilgili bir FK kısıtlamasından kaynaklanması durumunda FOR EACH STATEMENT tetikleyicisi ne sıklıkla çalışır?


11

Ben bir t FOR EACH STATEMENTyürüttüğümde ile tanımlanmış t tablo üzerinde bir tetikleyici çalışacağını anlıyorum UPDATE t ....

Şimdi, tile tanımlandığında FOREIGN KEY ... REFERENCES a ... ON UPDATE CASCADEve N satırını güncellediğimde a, tetikleyici bir kez mi yoksa N kez mi çağrılır?

Başka bir ifadeyle, bir FK kısıtlamasıyla bir tablodaki değişiklikler daha çok tekli mi UPDATEyoksa daha fazla UPDATEs serisi mi?


4
Bir test senaryosu oluşturabilirsiniz! Tetikleyicinin gövdesindeki başka bir tabloya yerleştirin ve kaç satır aldığınızı görün. O zaman bu soruya kendi cevabınızı yazın (izin verilir, hatta teşvik edilir)!
Colin 't Hart

2
Önde gelen cümle FOR EACH STATEMENT, sorunun geri kalanına diktir. FK kısıtlamaları özel tetikleyicilerle uygulanır FOR EACH ROW.
Erwin Brandstetter

1
@Erwin "HER SATIR İÇİN" veya "HER SATIŞ İÇİN" t?
ypercubeᵀᴹ

@ypercube: Ayrıntılarla bir cevap ekledim.
Erwin Brandstetter

Yanıtlar:


6

Yabancı anahtar kısıtlamaları şu anda özel dahili tetikleyicilerle uygulanmaktadır. Hepsi yönetilir FOR EACH ROW.

Bunların değişebilen uygulama ayrıntıları olduğunu unutmayın, bu yüzden ona güvenmeyin. Ancak, temel sürümlerin son birkaçında temeller değişmedi, bu nedenle büyük değişiklikler olası değildir.

Ben basit bir FK kısıtlaması ile hızlı bir testi yaptık tbletmek tbltype. Basit bir FK, sayfa 9.4'deki testimde dört basit dahili tetikleyici ile uygulanır FOR EACH ROW.
İşte araştırmak için hızlı bir özet:

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'

İki dahili "noaction" tetikleyicisi açılır tbltype.
İki dahili "kontrol" tetikleyicisi açık tbl.
Hepsi, FOR EACH ROWtek sayılarla gösterildiği gibi çalıştırılır tgtype.

Postgres'in 2 baytı, en az anlamlı bitin kodladığı C cinsinden tgtype smallintbir int16kaynak kodunu temsil eder TRIGGER_TYPE_ROW. Ayrıntılı açıklama burada:

Bunu sadece değiştirdiğiniz bir çift özdeş tetikleyici ile kolayca test edebilirsiniz FOR ROW/ STATEMENT...


5

N kez yürütülür ve bunu görmenin en kolay yolu ifadeyi EXPLAIN ANALYZEbaşa, yani

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

Bu size aşağıdakine benzer bilgiler verecektir:

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

(9.2 ile test edilmiştir)


1
Bu benim için biraz şaşırtıcı. Aynı sonuçlarla 9.4'te test edildi.
dezso
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.