I work with Postgres 11 and would like to change the index that backs the primary key of a large table (~750 million rows). The primary key is the bigint
column id
and I would like to include an extra column using the INCLUDE
term. This needs to happen without a table rewrite (i.e. no new/changed columns).
Dropping the current PRIMARY KEY
constraint isn't convenient, because a lot of other tables reference the target table. I suppose it would be possible to drop the FOREIGN KEY
constraints on all those tables, then drop the PRIMARY KEY
constraint, recreate using a new index and then recreate the FOREIGN KEY
constraints. Is there a better way to do it?
-
1I don't think there is a better way, currently. You might automate dropping and recreating FK constraints for convenience. Is concurrent read or write access of concern? Is (temporary) storage size of concern?Erwin Brandstetter– Erwin Brandstetter2019年08月19日 16:25:57 +00:00Commented Aug 19, 2019 at 16:25
-
Thanks, I was hoping something would get me around the FK recreation. Automating this might make this easier, yes, that's a good point. Storage should be fine for the additional index and creating the new index concurrently, will probably make the IO okay.tomka– tomka2019年08月19日 23:57:13 +00:00Commented Aug 19, 2019 at 23:57
1 Answer 1
Without messing with the catalogs (which is not commendable), the only option I can think of would require you to do without foreign keys for a while:
You can define a second UNIQUE
index on the table that contains the appropriate INCLUDE
clause.
If you use the CONCURRENTLY
clause of CREATE INDEX
, that shouldn't be disruptive.
Then you can delete the original primary key constraint and all dependent foreign keys using DROP INDEX ... CASCADE
.
Then use ALTER TABLE ... ADD CONSTRAINT ... USING INDEX
to turn the unique index into a primary key constraint.
Now you can re-create the foreign key constraints.
-
1True, I could define the new index before I delete the original one, which is probably a good idea in terms of data integrity. Unfortunately it doesn't get me around recreating all foreign key. Using
CREATE INDEX CONCURRENTLY
is certainly a good point, too.tomka– tomka2019年08月19日 23:53:36 +00:00Commented Aug 19, 2019 at 23:53 -
1I have revised my answer so that it actually works. You'd have to do without foreign keys for a while.Laurenz Albe– Laurenz Albe2019年08月20日 06:03:19 +00:00Commented Aug 20, 2019 at 6:03
Explore related questions
See similar questions with these tags.