Model Design Lab

100 Million Rows, One Fast Answer

An aggregation table pre-summarizes a giant fact table so most queries never touch the detail. The cube cloud below is 100M sales rows (each cube ≈ 40,000 rows). Toggle aggregation, pick a grain, then run queries and watch which ones hit the small table — and which fall through to the full scan.

drag to orbit · scroll to zoom
Active storage: detail fact table100,000,000 rows

Storage mode

Aggregation grain (date level)

Grain = Date[Month] × Product → 12,000 summary rows

Run a DAX query

Run a query to see whether it hits the aggregation or scans all 100M detail rows.

What lives inside a semantic model

Tables and relationships

A semantic model is not "a spreadsheet in the cloud" — it is a star schema: one wide fact table (Sales: date key, product key, store key, amount, quantity) surrounded by small dimension tables (Date, Product, Store, Customer). Relationships are one-to-many, dimension → fact, so a slicer on Product[Category] filters millions of Sales rows through a single join path.

Measures (the logic layer)

Measures are DAX expressions evaluated at query time in whatever filter context the visual creates:

Total Sales = SUM ( Sales[Amount] ) Sales YoY % = DIVIDE ( [Total Sales] - CALCULATE ( [Total Sales], DATEADD ( 'Date'[Date], -1, YEAR ) ), CALCULATE ( [Total Sales], DATEADD ( 'Date'[Date], -1, YEAR ) ) )

One definition, reused by every report — that is the "semantic" in semantic model.

Metadata that pays rent

  • Hierarchies (Year → Quarter → Month → Day) for drill-down
  • Formatting, display folders, descriptions
  • Row-level security roles filtering data per user
  • Aggregation mappings — the subject of this page
  • Storage mode per table: Import, DirectQuery, or Dual

When aggregations hit — and when they miss

The hit rule

A query hits the aggregation when everything it needs can be answered at or above the aggregation's grain, using only columns the aggregation covers. Monthly grain answers monthly, quarterly, and yearly questions. It can never answer a daily question — the detail is gone.

Classic misses

  • Grouping by a column not in the agg (Customer, Invoice #)
  • Finer date grain than the agg (daily vs monthly agg)
  • Measures the agg cannot derive: DISTINCTCOUNT of customers cannot be summed from monthly buckets
  • Filters on detail-only columns, even if the output looks coarse

Design guidance

  • Aggregate to the grain your top visuals actually use — audit with Performance Analyzer
  • Keep the agg table in Import mode, detail in DirectQuery ("Dual" dimensions bridge both)
  • Store SUM and COUNT, derive AVG = SUM / COUNT — never store averages
  • A 1,000x row reduction is common: 100M daily rows → 100k monthly rows
Enjoy this tool? Build your own with Super