Skip to the solution
EasyDSA14 min read

What does DISTINCT do and what is its cost?

859 views

The problem

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:

  • distinct

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

14 min read ยท 10 sections

Run the code

Edit the query and run it against the tables for this question.

SQLDISTINCT compares whole result rows, and treats NULLs as one value
SQLCOUNT(DISTINCT col) ignores NULLs; counting distinct pairs needs a subquery
SQLDISTINCT as a band-aid for join fan-out, and the EXISTS fix
SQLSQLite: DISTINCT needs a temporary B-tree, unless an index already provides the order
PostgreSQL: DISTINCT planned as a HashAggregate
EXPLAIN (COSTS OFF)
SELECT DISTINCT customer_id, product FROM orders;
PostgreSQL: with hash aggregation disabled, the same DISTINCT becomes Sort + Unique
SET enable_hashagg = off;
EXPLAIN (COSTS OFF)
SELECT DISTINCT customer_id, product FROM orders;
PostgreSQL DISTINCT ON: the latest order per customer
SELECT DISTINCT ON (customer_id) customer_id, product, amount, placed
FROM orders
ORDER BY customer_id, placed DESC, id DESC;

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 7 of 82 in SQL

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All SQL questions
Up nextEasy

How do you find duplicate rows in a table?

Continue