Question presented to candidate: "What does SELECT DISTINCT actually do, row by row? And when a colleague adds DISTINCT to a slow report query to get rid of duplicates, what does it cost the database, and what would you suggest instead?"
What a strong answer should cover:
- DISTINCT removes duplicate result rows, comparing the whole SELECT list, not one column; for DISTINCT, NULLs count as equal to each other
- It runs after SELECT and before ORDER BY, which is why PostgreSQL requires ORDER BY expressions to appear in the select list
- Cost: the engine must find duplicates, by sorting (Sort + Unique) or hashing (HashAggregate), using memory proportional to the distinct rows and spilling to disk past
work_mem; an index that already delivers rows in order can avoid that work - DISTINCT used to hide join fan-out is a smell: EXISTS (a semi-join) or fixing the join is cheaper and more correct
- Related forms: COUNT(DISTINCT col), GROUP BY as an equivalent, UNION vs UNION ALL, and PostgreSQL's DISTINCT ON for "one row per key"
Code / implementation expected: Optional โ a DISTINCT query and its plan, or a join fixed with EXISTS instead of DISTINCT.
Schema used by the examples: