I have an update statement that affects every row in a given table. For that table it changes the value in a single column, which itself has a foreign key constraint. The table has an additional 9 foreign keys, some of which reference large tables. My expectation would be that only the changed column would be checked against the foreign key of interest, instead I find that all the foreign keys are checked when this statement is executed. I decided to create a simple test case to demonstrate this behaviour, but what I found was strange. The first time I created the test cases the behaviour matches my experience but the second time I created it the behaviour was then as I would have expected. This is the result I am experiencing with the unnecessary foreign key verification: testdb=# explain analyze update t1 set B = 1; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..25.10 rows=1510 width=22) (actual time=0.026..0.029 rows=1 loops=1) Trigger for constraint fk1: time=0.111 calls=1 Trigger for constraint fk2: time=0.014 calls=1 Total runtime: 0.259 ms (4 rows) Only fk1's column is being updated, not fk2's. Below is both sessions. Any feedback on this and how to avoid it is appreciated as well as whether the developers would consider this a bug, I am inclined to believe so as it hurts performance. Thanks, -J ************************************* testdb=# create table t1 (A BIGINT, B BIGINT); CREATE TABLE testdb=# create table t2 (B BIGINT PRIMARY KEY); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t2_pkey" for table "t2" CREATE TABLE testdb=# alter table t1 add constraint fk1 foreign key (B) references t2 (B); ALTER TABLE testdb=# explain analyze insert into t2 values (1); QUERY PLAN ------------------------------------------------------------------------------------ Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.008..0.010 rows=1 loops=1) Total runtime: 45.508 ms (2 rows) testdb=# explain analyze insert into t1 values (1, 1); QUERY PLAN ------------------------------------------------------------------------------------ Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.008..0.010 rows=1 loops=1) Trigger for constraint fk1: time=0.256 calls=1 Total runtime: 0.345 ms (3 rows) testdb=# explain analyze update t1 set A = 2; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..27.70 rows=1770 width=14) (actual time=0.019..0.022 rows=1 loops=1) Total runtime: 0.125 ms (2 rows) testdb=# explain analyze update t1 set B = 1; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..27.70 rows=1770 width=14) (actual time=0.021..0.024 rows=1 loops=1) Total runtime: 0.115 ms (2 rows) testdb=# explain analyze update t1 set B = 1; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..27.70 rows=1770 width=14) (actual time=0.021..0.024 rows=1 loops=1) Total runtime: 0.113 ms (2 rows) testdb=# explain analyze insert into t2 values (2); QUERY PLAN ------------------------------------------------------------------------------------ Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.008..0.010 rows=1 loops=1) Total runtime: 0.120 ms (2 rows) testdb=# explain analyze update t1 set B = 2; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..27.70 rows=1770 width=14) (actual time=0.020..0.024 rows=1 loops=1) Trigger for constraint fk1: time=0.112 calls=1 Total runtime: 0.233 ms (3 rows) testdb=# explain analyze update t1 set A = 99; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..27.70 rows=1770 width=14) (actual time=0.021..0.025 rows=1 loops=1) Total runtime: 0.117 ms (2 rows) testdb=# alter table t1 add b2 bigint; ALTER TABLE testdb=# alter table t1 add constraint fk2 foreign key (B2) references t2 (B); ALTER TABLE testdb=# explain analyze update t1 set B = 1; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..25.10 rows=1510 width=22) (actual time=0.026..0.029 rows=1 loops=1) Trigger for constraint fk1: time=0.111 calls=1 Trigger for constraint fk2: time=0.014 calls=1 Total runtime: 0.259 ms (4 rows) testdb=# testdb=# testdb=# testdb=# testdb=# testdb=# drop table t1; DROP TABLE testdb=# drop table t2; DROP TABLE testdb=# create table t1 (A BIGINT, B BIGINT, B2 BIGINT); CREATE TABLE testdb=# create table t2 (B BIGINT PRIMARY KEY); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t2_pkey" for table "t2" CREATE TABLE testdb=# alter table t1 add constraint fk1 foreign key (B) references t2 (B); ALTER TABLE testdb=# alter table t1 add constraint fk2 foreign key (B2) references t2 (B); ALTER TABLE testdb=# insert into t2 values (1), (2); INSERT 0 2 testdb=# insert into t1 values (1, 1, 1); INSERT 0 1 testdb=# explain analyze update t1 set A = 2; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..25.10 rows=1510 width=22) (actual time=0.017..0.020 rows=1 loops=1) Total runtime: 0.118 ms (2 rows) testdb=# explain analyze update t1 set B = 2; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..25.10 rows=1510 width=22) (actual time=0.021..0.024 rows=1 loops=1) Trigger for constraint fk1: time=0.111 calls=1 Total runtime: 0.237 ms (3 rows) testdb=# explain analyze update t1 set B2 = 2; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..25.10 rows=1510 width=22) (actual time=0.023..0.026 rows=1 loops=1) Trigger for constraint fk2: time=0.117 calls=1 Total runtime: 0.252 ms (3 rows) testdb=# explain analyze update t1 set B2 = 1; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..25.10 rows=1510 width=22) (actual time=0.021..0.024 rows=1 loops=1) Trigger for constraint fk2: time=0.112 calls=1 Total runtime: 0.244 ms (3 rows) testdb=# explain analyze update t1 set B = 1; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..25.10 rows=1510 width=22) (actual time=0.021..0.024 rows=1 loops=1) Trigger for constraint fk1: time=0.111 calls=1 Total runtime: 0.237 ms (3 rows) testdb=# explain analyze update t1 set B = 1, b2 = 2; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..25.10 rows=1510 width=14) (actual time=0.021..0.024 rows=1 loops=1) Trigger for constraint fk2: time=0.111 calls=1 Total runtime: 0.236 ms (3 rows) testdb=# explain analyze update t1 set B = 1; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on t1 (cost=0.00..25.10 rows=1510 width=22) (actual time=0.022..0.025 rows=1 loops=1) Trigger for constraint fk1: time=0.112 calls=1 Total runtime: 0.237 ms (3 rows) -- Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-general