SQL: a foreign key does not create an index on the child

PostgreSQL and Oracle index the parent's key, not the child's column. Every delete on the parent then scans the whole child table to check for references.

Code
CREATE TABLE orders (
  id BIGSERIAL PRIMARY KEY,
  customer_id BIGINT REFERENCES customer(id)
);

-- No index on orders.customer_id. Add it:
CREATE INDEX idx_orders_customer ON orders (customer_id);

-- Find the missing ones:
SELECT conrelid::regclass AS child, a.attname
  FROM pg_constraint c
  JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = c.conkey[1]
 WHERE c.contype = 'f'
   AND NOT EXISTS (SELECT 1 FROM pg_index i
                    WHERE i.indrelid = c.conrelid AND i.indkey[0] = c.conkey[1]);
Output
DELETE FROM customer WHERE id = 7;
  without the index: Seq Scan on orders  (4.2 s on 8M rows)
  with the index:    Index Scan          (0.8 ms)

-- MySQL/InnoDB is the exception: it creates the child index automatically.
Advertisement

Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.

Published 2026-08-25