| From: | Manu <manuelreyesbravo(at)gmail(dot)com> |
|---|---|
| To: | Bernhard Wonisch <bernhard(dot)wonisch(at)gmx(dot)at> |
| Cc: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Re: ATTACH PARTITION cost grows linearly with pg_constraint size (seqscan in CloneFkReferenced), much worse since not-null constraints are in pg_constraint (PG 18) |
| Date: | 2026-09-29 12:35:49 |
| Message-ID: | 179068534958.116032.10264585643322645998@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi Bernhard,
Good report. I reproduced it and measured a few things around it.
The slowdown reproduces on 18.6. With your script, ms per ATTACH goes
from 0.07 (empty) to 20.7 at 1M pg_constraint rows, the nullable control
stays flat, and pg_stat_sys_tables shows exactly one pg_constraint
seqscan per ATTACH. My absolute numbers are lower than yours (faster
machine) but the shape is the same.
I also ran your script on 17.11, which you hadn't. It stays flat, 0.06
to 0.26 ms per ATTACH, and pg_constraint stays at ~110 rows the whole
way. The seqscan happens on 17 too, but with almost nothing in
pg_constraint it costs nothing. So this is 14e87ffa5 feeding a scan
that was always there, as you say.
On your option (c), one thing makes it cheaper than it looks: only
foreign-key rows have confrelid <> 0. I checked every contype, and
not-null, check, primary-key and unique constraints all store
confrelid = 0, so a partial index
CREATE INDEX ... ON pg_constraint (confrelid) WHERE confrelid <> 0;
covers only the FK rows, not the not-null rows that dominate the
catalog. On a database with 1,000,198 constraints of which 1 is an FK,
that index is 16 kB, and the lookup CloneFkReferenced() does drops from
a 58 ms seqscan (1M rows filtered) to a 0.03 ms index scan. The partial
predicate also answers the maintenance worry you raised for (c): the
not-null inserts that make up the bulk match confrelid = 0, so they
never touch the index.
One correction on the DETACH path: I could not reproduce a slowdown
there. Detaching 50 partitions with 1M pg_constraint rows stays at
0.06 ms each and adds zero pg_constraint seqscans, so
GetParentedForeignKeyRefs() does not seem to be reached on a plain
DETACH with no foreign key involved. ATTACH is where the cost is.
I'd be glad to put a patch together once there's a sense of the
preferred direction. The partial index is the smallest change, but
whether a new catalog index is the way to go, versus the pg_depend
lookup or the trigger-based early exit, is more your and the
committers' call. Happy to test any of them against the reproducer.
Regards,
Manu
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Kirill Reshke | 2026-09-29 12:37:39 | Re: RI fastpath misses checking EXECUTE on functions |
| Previous Message | Narayanan Venkateswaran | 2026-09-29 12:26:14 | Re: Proposal: Conflict log history table for Logical Replication |