Schema Foreign Key Indexes
title: Index Foreign Key Columns impact: HIGH impactDescription: 10-100x faster JOINs and CASCADE operations tags: foreign-key, indexes, joins, schema
Section titled “title: Index Foreign Key Columns impact: HIGH impactDescription: 10-100x faster JOINs and CASCADE operations tags: foreign-key, indexes, joins, schema”Index Foreign Key Columns
Section titled “Index Foreign Key Columns”Postgres does not automatically index foreign key columns. Missing indexes cause slow JOINs and CASCADE operations.
Incorrect (unindexed foreign key):
create table orders ( id bigint generated always as identity primary key, customer_id bigint references customers(id) on delete cascade, total numeric(10,2));
-- No index on customer_id!-- JOINs and ON DELETE CASCADE both require full table scanselect * from orders where customer_id = 123; -- Seq Scandelete from customers where id = 123; -- Locks table, scans all ordersCorrect (indexed foreign key):
create table orders ( id bigint generated always as identity primary key, customer_id bigint references customers(id) on delete cascade, total numeric(10,2));
-- Always index the FK columncreate index orders_customer_id_idx on orders (customer_id);
-- Now JOINs and cascades are fastselect * from orders where customer_id = 123; -- Index Scandelete from customers where id = 123; -- Uses index, fast cascadeFind missing FK indexes:
select conrelid::regclass as table_name, a.attname as fk_columnfrom pg_constraint cjoin pg_attribute a on a.attrelid = c.conrelid and a.attnum = any(c.conkey)where c.contype = 'f' and not exists ( select 1 from pg_index i where i.indrelid = c.conrelid and a.attnum = any(i.indkey) );Reference: Foreign Keys