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.
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]);
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.
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