Foreign Keys
Adding a foreign key without NOT VALID takes SHARE ROW EXCLUSIVE on both the source and referenced table and scans the entire table to validate existing rows.
The Problem
sql
-- SHARE ROW EXCLUSIVE on posts AND users, full table scan
ALTER TABLE posts ADD CONSTRAINT fk_posts_user_id
FOREIGN KEY (user_id) REFERENCES users(id); Safe Rewrite
sql
SET lock_timeout = '2s';
-- NOT VALID: brief SHARE ROW EXCLUSIVE for metadata only, no table scan
ALTER TABLE posts ADD CONSTRAINT fk_posts_user_id
FOREIGN KEY (user_id) REFERENCES users(id) NOT VALID;
-- VALIDATE: SHARE UPDATE EXCLUSIVE, non-blocking scan of existing rows
ALTER TABLE posts VALIDATE CONSTRAINT fk_posts_user_id;