The DISTINCT in Your COUNT

One tiny word turns a simple user count into a one-core slog — and commenters are not impressed

TLDR: Adding “distinct” to a simple user count makes Postgres stop using multiple cores, which can turn a fast scan into a slow, disk-heavy chore. Commenters quickly hijacked the story with approximation hacks, outside links, and one blunt swipe accusing the article of being AI-written.

A perfectly innocent-looking database question — “how many different users do we have?” — turned into a full-blown performance horror story once one word entered the chat: DISTINCT. The article shows that in Postgres, a plain count can spread the work across multiple CPU cores, but add “distinct” and suddenly it’s one worker, one giant sort, and even a trip to disk. In regular-person terms: the database goes from “team effort” to “one exhausted employee doing all the filing alone.”

But the real fireworks came from the comments, where the crowd instantly split into helpful math nerds versus skeptics with their claws out. One camp rushed in with “why not just estimate it?” and pointed to the wonderfully named Flajolet–Martin algorithm, a clever shortcut for getting an approximate answer without all the painful sorting. Another commenter backed that vibe with a Snowflake blog link, basically saying: this problem is so common there’s already a whole side quest for it.

Then came the spicy drive-by: one user said it was “Hard to make a case to engage with an AI written article”, which instantly shifted the mood from database gripe session to content authenticity drama. So yes, the tech lesson is that a tiny keyword can make a big query dramatically slower. But the comment-section lesson? On the internet, even a post about counting users can become a referendum on algorithms, shortcuts, and whether the article itself passes the vibe check.

Key Points

  • The article shows that `COUNT(DISTINCT user_id)` in PostgreSQL does not use parallel query, unlike `COUNT(*)`.
  • In the example, a plain `count(*)` uses a parallel plan with four workers, `Parallel Seq Scan`, `Partial Aggregate`, and `Finalize Aggregate`.
  • Adding `DISTINCT` changes the plan to a single-process sequential scan followed by a sort and aggregate, with no `Gather` or partial aggregation.
  • The example sort for `COUNT(DISTINCT user_id)` exceeds `work_mem` and spills about 115MB to temporary disk storage.
  • The article attributes the lack of parallelization to PostgreSQL's aggregate model: distinct counting cannot be merged from small worker-local summaries without tracking overlapping values across workers.

Hottest takes

"fits on 10 lines and does not require sorting" — muth02446
"Hard to make a case to engange with an AI written article" — thecaio
"In the same vein" — natmaka
Made with <3 by @siedrix and @shesho from CDMX. Powered by Forge&Hive.