SQL: EXISTS stops at the first match, IN builds the whole list

EXISTS asks a yes/no question and can stop as soon as one row qualifies. IN materialises the subquery result. For a large subquery with duplicates, EXISTS is usually the better plan.

Code
SELECT c.name FROM customer c
 WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);

SELECT c.name FROM customer c
 WHERE c.id IN (SELECT customer_id FROM orders);

-- SELECT 1 vs SELECT * inside EXISTS makes no difference at all - the
-- column list is never evaluated.
Output
EXISTS : Hash Semi Join   ->  31 ms
IN     : Hash Semi Join   ->  33 ms      (planner rewrote it)

-- For simple cases modern planners produce the same semi-join. They diverge
-- when the subquery can return NULL - and NOT IN then breaks entirely, which
-- is the real reason to prefer NOT EXISTS.
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