The untidy shape that answers faster
A Socratic walk-through of the untidy shape that answers faster — reasoned out one step at a time, not lectured.
The question we started with
THE QUESTION #Why does the arrangement that looks less orderly return answers more quickly?
Anyone trained on database design learns that repetition is a defect. If every product row repeats its brand name, and every brand row repeats its category name, you normalise: pull the repeating thing into its own table and point at it. Each fact recorded once, cleanly.
Then you look at a working data warehouse and find a product dimension with brand, category, department and supplier all sitting redundantly in the same wide table, repeated across millions of rows — and it answers questions faster than the tidy version. That is not a small anomaly to explain away. It suggests the tidiness rule was never a rule about tables; it was a rule about something else, which no longer applies here.
Reasoning it through
REASONING #So ask the sharper question: what problem does normalisation actually solve?
Update anomalies. If a brand's name appears in a million rows and the brand is renamed, you must change a million rows, and if you change only some, the database now holds two contradictory answers. Normalising to one row means one update, and inconsistency becomes structurally impossible.
Now hold that against a warehouse. How are its rows changed? Mostly they are not. Facts are loaded and thereafter read; dimension attributes change slowly and are handled deliberately, often by adding a new version of the row rather than overwriting. The anomaly normalisation exists to prevent is close to absent — and yet you are still paying its price, in joins, on every single query.
That is the whole reversal in one line: normalisation is a write-time protection charged at read time. In a system that reads a thousand times per write, the accounting comes out the other way round.
Then what does the price consist of? Suppose you ask for revenue by product category. In the snowflaked shape, the query walks fact to product to brand to category — a chain, and each link must be resolved before the next can be. In the star, the category is a column on the product dimension: fact to product, one hop, and category is simply there.
Two costs are hidden in that chain. The obvious one is the work of the joins themselves. The subtler one is the optimiser's job: the number of possible orderings of a join grows explosively with the number of tables, so a planner given five tables has vastly more ways to be wrong than one given two. Star schemas are not merely faster to execute; they are far more predictably fast, because there is less for the planner to get wrong.
There is a third reason, less discussed and quite practical. Business intelligence tools generate SQL from a model. Given a star, the generated query is nearly always fact-plus-dimensions and comes out the same shape every time. Given a snowflake, the generated SQL varies with which attribute the user dragged in, and performance varies with it.
Now the honest correction, because the classic argument is often overstated. The storage saving from snowflaking is usually negligible on a modern columnar engine: repeated values compress extremely well under dictionary and run-length encoding, so a "wasteful" repeated category string may cost almost nothing on disk. And the join penalty has narrowed too — engines with broadcast joins and runtime filtering handle small dimension tables well. So the modern case for the star is less about raw speed than it was in the 1990s, and more about comprehensibility and predictability. Anyone quoting a large fixed speed multiple is quoting an old benchmark.
Where does snowflaking still earn its place? When a dimension is genuinely enormous, when a hierarchy is shared across several fact tables and must not drift between them, or when the hierarchy itself changes often enough that maintaining it in one place is worth a join. Those are real cases; they are just not the default one.
The analogy
THE ANALOGY #Think of a reference book with an index versus a book with cross-references. The cross-referenced book is elegant: each fact stated once, and every other mention points to it. Look something up and you follow the pointer to page 340, which sends you to page 12, which sends you to the appendix. Nothing is repeated, and every lookup is a walk. The indexed book repeats things — the same date printed in four entries — and every lookup lands in one place. If the book is being revised constantly, the cross-referenced form protects you from contradicting yourself. If it is printed once and read by thousands, the repetition is simply the right choice.
a printed book cannot be revised at all, whereas a warehouse dimension genuinely does change — so the star does not escape the update problem, it moves it into the loading process, where slowly changing dimension handling deals with it deliberately rather than relying on the schema shape to prevent it.
Clarifying the model
THE MODEL #Three refinements.
First, the misconception that a star schema is normalisation done badly. It is normalisation deliberately not applied, for a system whose read-to-write ratio inverts the reason for it. The transactional system upstream should still be fully normalised — it is where the updates happen, and that is exactly where anomalies would bite.
Second, the star's real product is not speed but a stable interface. Any question about the business becomes the same shape of query: pick the fact table, join the dimensions you filter or group by, aggregate. A user who learns that shape once can ask anything. A snowflake requires knowing the topology of the hierarchy before you can write the query at all.
Third, this is not an all-or-nothing choice. Many warehouses snowflake one troublesome hierarchy and keep everything else flat, which is fine — the shapes describe individual dimensions, not a doctrine the whole model must obey.
A picture of it
THE PICTURE #How to readThe three edges leaving the fact table are the star: every dimension is one hop away, so any question is fact plus a join. The two edges hanging off the product dimension are the snowflake, and they are the whole argument — an attribute that could have been a column now costs two further joins, and a query grouping revenue by category must traverse all three links in order rather than reading one column. Count the hops to an attribute, and you have counted the cost of asking about it.
What became clearer
WHAT CLEARED #Normalisation is not a universal virtue; it is a specific defence against update anomalies, purchased with joins. A warehouse barely updates and constantly reads, so it pays the premium without receiving the cover — and the redundant, untidy-looking star is the shape that stops paying for insurance it does not need.
Where to go next
ONWARD #- Slowly changing dimensions: how the star handles attribute change without normalising.
- Why columnar compression makes redundant dimension attributes nearly free to store.
- One big table designs, which push denormalisation further still, and where they stop working.
Key terms
TERMS #| Term | What it means |
|---|---|
| Star schema | a central fact table joined directly to denormalised dimension tables, each one hop away. |
| Snowflake schema | a star whose dimension hierarchies are normalised into further tables, adding join depth. |
| Update anomaly | an inconsistency arising when a repeated fact is changed in some copies and not others. |
| Join depth | the number of sequential joins a query must resolve to reach an attribute. |
| Slowly changing dimension | the deliberate technique for recording changes to dimension attributes over time, usually by versioning rows. |
Every term the collection defines is gathered in the glossary.