when people first open power bi, they usually jump straight into visuals. charts, slicers, maps—it feels like that’s where the real action is. but the longer you work with it, the more you realize that the real magic is happening underneath, in the way the data is shaped and modeled. the model is the engine, and without the right engine, even the best-looking report falls apart. that’s where the star schema comes in. it’s the moment power bi stops feeling confusing and starts making sense.
think of power bi desktop as the workshop. it brings in data from wherever it lives, lets you clean it up with power query, and gives you a canvas to shape how everything relates. but the trick isn’t just getting the data in—it’s organizing it so power bi can think clearly. when you structure your data in a star schema, something clicks. suddenly measures work the way you expect. filters behave predictably. visuals respond faster. and the model becomes easy to explain to anyone, even people who’ve never heard of dax.
the heart of the star schema is simple: one big table that holds the numbers—sales, quantities, durations, events—and several smaller tables that describe the world around those numbers. dates. products. customers. regions. the fact table sits in the middle, the dimensions radiate around it, and power bi finally has a clean map of how everything connects. you stop fighting the model and start building with it.
You unlock powerful insights when you use the right data model in Microsoft Power BI. A star schema in Power BI helps you organize your data for faster analysis and clearer results. Most bi developers choose this method because it delivers a business intelligence solution that is easy to maintain.
- 80% of Power BI users building star schema models report improved performance and analysis efficiency compared to other approaches.
If you skip the star schema, you face common challenges:
| Challenge | Description |
|---|---|
| Slow performance | Too much redundancy and duplication. |
| Complicated DAX formulas | Relationships aren’t clear. |
| Difficult maintenance | Hard to scale when new data comes in. |
Key Takeaways
- A star schema improves performance and analysis efficiency in Power BI, making it a preferred choice for BI developers.
- Careful planning is essential before building your star schema. Understand your data and map out your schema to avoid confusion.
- Use numeric keys for joins to speed up queries and ensure reliable relationships between tables.
- Define clear fact and dimension tables. Fact tables should capture business metrics, while dimension tables provide context.
- Maintain high data quality in your dimension tables by removing duplicates and standardizing formats.
- Set up one-to-many relationships between fact and dimension tables to optimize query performance.
- Regularly audit your data model to remove unused tables and ensure efficient resource management.
- Optimize your model by reducing data size and improving refresh speed, leading to faster and more reliable reports.
9 Surprising Facts about Power BI Data Modeling with Star Schema
- Star schema isn't just a performance pattern — it improves DAX simplicity: Measures written over a clear fact and dimension layout are far easier to author and debug than formulas across highly normalized models.
- VertiPaq compression favors denormalized designs: Repeating dimension keys and text in a star schema often compress better and query faster than deeply normalized tables because VertiPaq groups and encodes columns efficiently.
- Bidirectional cross-filtering can break the star model advantage: Enabling many-to-many or bi-directional filters may convert the effective model into a complex network, harming performance and producing ambiguous filter context.
- Inactive relationships are powerful for time-intelligence: Keeping multiple date relationships inactive and activating them in measures (USERELATIONSHIP) preserves a clean star design while supporting scenarios like invoice date vs ship date.
- Composite models blur the DirectQuery vs Import boundary: You can keep a star schema in import for facts and use DirectQuery for slow-changing dimensions, but mixing modes affects relationship behavior and some DAX functions.
- Marking the date table matters: Marking a proper date table in Power BI unlocks built-in time intelligence and ensures correct behavior for CALCULATE filters and many visuals; an unmarked date table can lead to subtle, incorrect results.
- Surprising cardinality impact: Using high-cardinality text keys in relationships can degrade performance — replacing them with surrogate integer keys in the star schema usually yields much faster joins and smaller model size.
- Aggregations accelerate big fact tables without changing star semantics: Defining aggregation tables that map to grain levels lets Power BI route queries to pre-aggregated data while preserving measure logic written against the base fact table.
- Q&A and visuals prefer stars: Natural-language Q&A and many visuals rely on clear dimension labels and single-hop relationships; a proper star schema noticeably improves Q&A accuracy and the reliability of slicer/report interactions.
Plan Your Star Schema in Power BI
Before you start building in Power BI, you need a clear plan for your star schema. Careful planning helps you avoid confusion, speeds up your reports, and makes your model easier to maintain. As a bi developer, you should always understand your data and map out your schema before importing anything into Power BI Desktop.
Analyze Data Sources
Identify Key Tables
Start by reviewing your data sources. Look for tables that contain business events, such as sales transactions or inventory movements. These will become your fact table. Next, find tables that describe business entities, like products, customers, or dates. These will serve as your dimension tables.
Tip: Use numeric keys for joins. Numeric keys speed up queries and make relationships more reliable.
Map Relationships
Draw a diagram to visualize how your tables connect. Make sure each fact table links directly to its dimension tables. Avoid connecting two fact tables together. This structure keeps your model simple and prevents confusion in your reports.
- Fewer joins during query execution lead to better performance.
- Strong, unambiguous relationships help filters work as expected.
- One-to-many relationships between fact and dimension tables improve scalability.
Design Schema Structure
Define Fact Table
Your fact table should capture the main business metrics you want to analyze, such as sales amount, quantity, or profit. Each row in the fact table represents a single business event at the lowest level of detail you need. Proper grain definition ensures correct aggregation and prevents double-counting.
| Table Type | Description | Example Columns |
|---|---|---|
| Fact Table | Stores business events and metrics | SaleID, DateKey, ProductKey, SalesAmount |
| Dimension Table | Describes entities related to the facts | ProductName, Category, CustomerName |
Define Dimension Tables
Dimension tables provide context for your facts. They should be descriptive and easy to understand. Normalize your dimensions enough to avoid redundancy, but keep them simple for reporting. Use unique values in each dimension to ensure accurate filtering.
Note: When a product is renamed, the ETL process creates a new row in the dimension table with a new key. The fact table keeps the old key for historical records. This approach ensures your reports show the correct product names for both past and current sales.
Best Practices for Planning
- Ensure facts and dimensions are only one step apart.
- Never join two fact tables directly.
- Use surrogate keys for stability and speed.
- Stick to consistent naming conventions.
- Document your schema for future reference.
A well-planned star schema in Power BI leads to faster queries, easier maintenance, and more reliable insights. You set yourself up for success by following these steps before you build your model.
Import Data into Power BI
Importing your data into Power BI sets the foundation for a reliable star schema. You need to connect to your data sources, clean and transform your data, and load your tables with care. Each step ensures your model stays accurate and performs well.
Connect to Data Sources
You can connect Power BI to many data sources, such as Excel files, SQL databases, or cloud services. Choose the source that holds your fact and dimension tables. Power BI Desktop makes this process simple with its user-friendly interface.
Use Power Query
Power Query acts as your data preparation tool. You use it to shape and refine your data before it enters your model. Power Query lets you filter rows, remove columns, and merge tables. You can also apply transformations like splitting columns or changing data types.
- Power Query’s ‘Enable Load’ setting helps you control which tables enter your model. Only enable loading for tables you need in your star schema.
- Cleanse and standardize key columns before merging tables. This step prevents duplicate records and improves join efficiency.
- Apply aggregations at the query level to limit the amount of data loaded into Power BI.
Clean and Transform Data
Cleaning your data means removing errors, fixing inconsistencies, and standardizing formats. You should check for missing values and correct them. You also need to make sure that key columns, such as ProductKey or CustomerKey, use the same format across all tables.
Merging data with care and applying aggregation techniques are crucial for maintaining model integrity and ensuring analytical accuracy. When merging datasets, include only unique and relevant records. Aggregating data during merges—using functions like minimum, maximum, or sum—helps avoid duplication and keeps your dimension tables clean.
Load Tables
After you prepare your data, you load your tables into Power BI. This step brings your fact and dimension tables into the model, ready for relationship mapping.
Structure and Rename Tables
Give each table a clear and descriptive name. Use names like "SalesFact" or "ProductDim" to show the table’s role. Consistent naming helps you and your team understand the model at a glance.
- Regularly audit your data model to identify and disable tables that are no longer needed for reporting.
- Document your data model architecture to keep track of transformations and dependencies.
- Implement incremental refresh policies for large datasets to reduce processing overhead.
Effective resource management within Power BI models involves a combination of techniques, including disabling unused tables, reducing column cardinality, and minimizing data duplication. Avoiding the loading of redundant tables prevents unnecessary bloat in memory usage, allowing Power BI to refresh datasets more swiftly and render dashboards without lag.
By following these steps, you ensure your star schema in Power BI remains efficient, accurate, and easy to maintain.
Create Dimension Table in Power BI
A well-designed dimension table is the backbone of your star schema. You use dimension tables to describe the details of your business, such as products, customers, or dates. These tables help you filter, group, and drill into your data for deeper analysis.
Extract Attributes
When you build a dimension table, you must choose the right attributes. These attributes should support the filtering, grouping, and hierarchy needs of your reports. You want each attribute to be relevant for analyzing all related fact tables. For example, a product dimension table might include product name, category, and brand.
- Choose attributes that users will use for filtering and grouping.
- Make sure each attribute helps with analysis across all fact tables.
- Consider if you need to support slowly changing dimensions, like when a product name changes over time.
- Include translations if your reports need to support multiple languages.
- Avoid adding unnecessary or redundant data, as this can increase the size of your model.
Remove Duplicates
You need to remove duplicate records from your dimension table. Duplicates can cause confusion and lead to incorrect results in your reports. Use Power Query to find and remove any repeated rows. Always check that each key in your dimension table is unique.
Tip: Unique keys in your dimension table ensure that filters work correctly and your star schema remains reliable.
Ensure Data Quality
High-quality data leads to accurate analysis. You should check for missing values, spelling errors, and inconsistent formats. Standardize your labels and fix any mistakes before loading the table into Power BI. Clean data in your dimension table makes your reports easier to use and understand.
Build Hierarchies
Hierarchies in your dimension table let you explore data at different levels. For example, you can create a date hierarchy with year, quarter, month, and day. You can also build hierarchies for products, regions, or organizations.
- Hierarchies allow you to drill down from summary data to details.
- You can create hierarchies by dragging and dropping fields in Power BI.
- Users can expand or collapse levels in visuals for better data exploration.
- Common hierarchies include date, product category, and region.
Add Calculated Columns
Sometimes, you need extra columns in your dimension table for analysis. You can add calculated columns in Power BI to create new attributes, such as full product descriptions or combined location fields. Calculated columns help you enrich your dimension table without changing the source data.
Set Data Types
Setting the correct data types is important for your dimension table. Assign text, number, or date types to each column as needed. This step ensures that Power BI sorts and filters your data correctly. Proper data types also improve performance and make your star schema easier to use.
Note: Always review your dimension table after loading it into Power BI. Check that all attributes, hierarchies, and data types support your reporting needs.
By following these steps, you create a strong dimension table that supports fast, flexible analysis in your star schema. You set the stage for clear, reliable business intelligence in Power BI.
Build Fact Table in Power BI
A well-structured fact table forms the core of your star schema. You use the fact table to store business events and metrics, such as sales transactions, quantities, or revenue. Building an effective fact table in Power BI ensures your reports run quickly and deliver accurate results.
Aggregate Data
You need to aggregate your data before loading it into the fact table. Aggregation reduces the volume of data and improves performance, especially when you work with large datasets.
Summarize with DAX or Power Query
You can create aggregation tables inside Power BI using Power Query or DAX functions. These tools let you group data, calculate totals, and remove unnecessary details. You can also build aggregated tables in your data warehouse or use Auto Aggregations in Power BI Premium. Dataflows in Power BI or Fabric Data Factory offer more options for building aggregations.
- Build the aggregation table inside Power BI using Power Query or DAX.
- Create pre-aggregated tables in your data warehouse.
- Use Auto Aggregations in Premium capacities.
- Build aggregations through Dataflows or Fabric Data Factory.
Aggregation tables help Power BI cache results from large datasets. This reduces the load on the main fact table and speeds up DAX calculations and visuals. When you use aggregation, you make your star schema more efficient.
Set Granularity
Granularity defines the level of detail in your fact table. You should decide if each row represents a single transaction, a daily summary, or another level. Consistent granularity prevents double-counting and ensures accurate analysis. For example, if your fact table tracks sales, each row might show one sale per product per day.
Tip: Set the lowest level of detail you need for analysis. This makes it easier to link the fact table to each dimension table and keeps your model simple.
Link to Dimension Tables
After you build your fact table, you must connect it to each dimension table. These relationships allow you to filter and analyze your data from different angles.
Create Relationships
Power BI often creates relationships automatically, but you should always check them. Use the Model tab and Manage relationships to edit or create links between your fact table and each dimension table. Make sure every foreign key in the fact table matches a primary key in the dimension table. This process ensures referential integrity and prevents missing or orphaned data.
| Step | Description |
|---|---|
| 1 | Check the relationships that Power BI has automatically created. |
| 2 | Use the Model tab to edit or create relationships. |
| 3 | Ensure relationships are correct for accurate reports. |
Maintaining referential integrity leads to faster performance and cleaner relationships in Power BI. It also ensures your star schema delivers reliable insights.
Set Cardinality
Cardinality describes how tables relate to each other. In a star schema, you usually set a one-to-many relationship from each dimension table to the fact table. This setup allows each value in the dimension table to match many rows in the fact table. Setting the correct cardinality helps Power BI optimize queries and improves report speed.
Note: Proper cardinality and referential integrity make your fact table and dimension table work together seamlessly. This is key for a high-performing star schema.
When you follow these steps, you create a fact table that supports fast, accurate analysis in Power BI. You also ensure your star schema remains easy to use and maintain.
Set Up Star Schema Relationships
Building relationships is a critical step when you design a star schema in Power BI. You connect your fact table to each dimension table, which allows you to filter, group, and analyze data efficiently. Proper relationship setup improves query speed and ensures your data model delivers accurate results.
Configure Relationships
You need to configure relationships between tables to create a strong foundation for your star schema. Power BI lets you manage these connections in the Model view.
One-to-Many Setup
Set up one-to-many relationships between your dimension table and fact table. This means each value in the dimension table links to multiple rows in the fact table. One-to-many relationships help Power BI optimize queries and reduce row scans.
- Use integer-type columns for keys to boost performance.
- Prefer one-to-many relationships over many-to-many or one-to-one.
- Merge tables if you find unnecessary one-to-one relationships.
- Remove inactive relationships that never get used.
Tip: One-to-many relationships ensure unique values in your dimension table and prevent ambiguity in filtering.
Cross-Filter Direction
Choose the correct cross-filter direction for each relationship. Single direction filtering is best for most star schema models. It keeps your data model simple and avoids confusion.
- Keep cross-filter direction single to maintain performance.
- Avoid bi-directional filtering unless you have a specific need.
- Limit cross-table dependencies to prevent circular relationships.
Note: Single direction filtering helps you avoid performance bottlenecks and makes your reports easier to maintain.
Validate Model
After you configure relationships, you must validate your star schema. Testing ensures your data model works as expected and delivers reliable insights.
Test with Reports
Create sample reports to check if filters and slicers work correctly. Use visuals to confirm that totals match your raw data and that formulas return accurate results.
- Check that each filter on a dimension table affects the fact table as intended.
- Validate that KPIs and measures follow approved business definitions.
- Test drill-downs and hierarchies to ensure flexible reporting.
Always compare report totals with source data to catch errors early.
Optimize Performance
Optimizing relationships in your star schema improves report speed and user experience. You can use several strategies to make your data model more efficient.
| Strategy | Explanation |
|---|---|
| Manage Cardinality | Set correct cardinality to enhance query performance and reduce row scans. |
| Efficient Joins | Direct connections between dimension tables and the fact table improve speed. |
| Simplified Aggregation | Power BI summarizes data efficiently, boosting performance. |
| Flexible Filtering & Drill-Downs | Dynamic reporting across dimensions enhances user experience. |
- Remove unused columns and filter data at the source.
- Aggregate data before loading to reduce size.
- Avoid many-to-many relationships, which can cause incorrect results and slow performance.
- Flatten snowflake structures into a star schema to minimize joins and improve responsiveness.
Power BI’s VertiPaq engine processes star schema models faster because they require fewer joins and less complex queries.
You build a robust star schema in Power BI when you follow these best practices. Proper relationships, validation, and optimization lead to faster reports, easier maintenance, and more reliable business intelligence.
Use Star Schema for Reporting

When you use a star schema in Power BI, you make reporting faster and easier to understand. This structure helps you build visuals, create measures, and optimize your model for the best performance.
Build Visuals
You can create powerful visuals in Power BI when your data model follows a star schema. The central fact table holds your business events and numbers, while each dimension table gives you the details you need for filtering and grouping.
Filter with Dimensions
You can filter your reports using fields from the dimension table. For example, you might filter sales by product category or customer region. This setup makes your dashboards interactive and easy to use.
- You can drag fields from dimension tables into slicers or filters.
- Users can explore data by different categories, dates, or locations.
- Filtering with dimensions keeps your reports clear and focused.
Tip: When you filter with dimensions, you help users find answers quickly and make better decisions.
Create Measures
You can create measures in Power BI to calculate totals, averages, or other key metrics. The star schema makes this process simple because the fact table stores all the numbers you need.
- You can write DAX formulas that sum, count, or average values in the fact table.
- Measures work well because the relationships between tables are clear.
- You can build complex KPIs without confusion.
Here are some reasons why creating measures is easier with a star schema:
- The fact table links directly to each dimension table.
- You can analyze complex datasets with simple queries.
- Power BI dashboards become more intuitive and responsive.
- Teams can monitor KPIs and track performance with confidence.
| Benefit | Star Schema | Snowflake Schema |
|---|---|---|
| Query Performance | Faster due to fewer joins required | Slower due to additional joins |
| DAX Calculation | Simplified, leading to improved measure creation | More complex, potentially slowing down calculations |
| Report Responsiveness | Enhanced, making reports more interactive | Reduced, due to performance overhead from joins |
| Data Organization | Central fact table with surrounding dimensions | Normalized dimensions leading to complexity |
| Compression Efficiency | Denormalized dimensions compress efficiently | Normalized tables may not compress as well |
Optimize Model
You can keep your Power BI reports fast and reliable by optimizing your model. A well-designed star schema helps you manage data size and improve refresh speed.
Manage Data Size
You should reduce the size of your model to make reports load faster and use less memory. You can remove unused columns, filter out unnecessary rows, and use aggregate tables.
| Technique | Description |
|---|---|
| Use Star Schema | A star schema is easy to understand and helps in faster report performance due to fewer joins. |
| Cardinality Optimization | Reduces the complexity of relationships, making the model cleaner and easier to maintain. |
| Use of Aggregate Tables | Improves performance by pre-calculating and storing summarized data for faster access. |
- You can keep your model easy to understand.
- You can improve report performance by reducing relationship complexity.
- You can use aggregate tables to speed up calculations.
Improve Refresh Speed
You can make your reports refresh faster by optimizing your model. When you reduce data size and use efficient relationships, you see big improvements.
| Metric | Before Optimization | After Optimization | Improvement |
|---|---|---|---|
| Model Size | ~4 GB | ~400 MB | 90% Reduction |
| Report Load Time | ~30 seconds | ~3 seconds | 10-20x Faster |
| User Complaints | Frequent | None | Positive Feedback |
Note: Experienced BI professionals choose star schemas because they have learned that this structure leads to faster, more reliable reports.
When you follow these steps, you create a Power BI model that is easy to use, quick to refresh, and ready for business insights.
You gain faster queries, simpler DAX, and easier maintenance when you build a star schema in Power BI. The table below shows how this data model improves performance:
| Benefit | Star Schema | Poor Model |
|---|---|---|
| Query Speed | Faster queries | Slow performance |
| Data Compression | Better compression | High memory usage |
| DAX Complexity | Simpler DAX | Complex DAX |
| Maintenance | Easier maintenance | Unpredictable filters |
Keep your star schema efficient by validating relationships, reducing model size, and marking date tables. Practice ongoing checks and explore resources for deeper learning.
This article explains why the star schema is the optimal design for your model and offers guidance for effective dimensional modeling.
Power BI Star Schema Checklist (Data Modeling & Power Query)
data model and power query: create a star schema for better insights
What is a Power BI star schema and why is it important?
A Power BI star schema is a data modeling pattern where a central fact table contains measurable events and is surrounded by dimension tables that describe attributes (like customer, date, product). This star schema design improves performance and usability for data analysis, supports complex analytics, and makes relationships between dimensions and the fact table straightforward for modeling in Power BI and the power bi semantic model.
How do I create a star schema in Power Query and load the data?
To create a star schema in Power Query, get your data from source systems (CSV file, relational data warehouses, or a single source) and shape tables into one fact table and multiple dimension tables using transformations. Use power query to split, pivot, clean, and normalize attributes so each dimension table contains related tables of descriptive columns and the fact table contains key values and numeric measures. Then load the data to the Power BI model and establish foreign key relationships.
What should the fact table contain and how many fact tables do I need?
The fact table contains measurable metrics, transactional rows (sales, clicks, quantities) and foreign keys that link to dimensions. A star schema is best when you have one fact table for a single subject area; if you have multiple business processes, you may design a data model with multiple fact tables but still follow star schema principles to avoid a giant fact table or a single table that mixes measures and attributes.
How do surrogate keys and index column usage help in a star schema?
Surrogate key values (often implemented as an index column) are artificial keys created during data integration to uniquely identify rows in dimension tables when source system keys are inconsistent or missing. Using surrogate key and index column helps maintain stable relationships between dimensions and the fact table, supports slowly changing dimensions (type 2), and improves performance optimization by avoiding complex composite keys.
When should I denormalize versus normalize dimension tables (snowflake dimensions)?
Star schema typically favors denormalized dimension tables to keep each dimension table contains descriptive attributes and simplify queries; however, if you have complex hierarchies you may use snowflake dimensions to normalize related attribute tables. Normalization reduces redundancy but can add joins; choose denormalization for performance and user-friendly modeling in Power BI, and snowflake dimensions only when needed for data integrity or to mirror relational data warehouses.
How do I handle slowly changing dimensions (type 2) in Power BI semantic model?
For type 2 slowly changing dimensions, create new dimension rows with new surrogate key values and track effective date and expiry date columns in the dimension table. The fact table should link to the correct surrogate key for historical accuracy. You can implement logic in Power Query to create and maintain these historical rows and use DAX for time-aware measures when building dashboards and reports.
What are best practices for relationships between dimensions and the fact table?
Best practices include using single direction or bidirectional relationships only when necessary, ensuring foreign key columns in the fact table match surrogate key types in dimension tables, and creating one-to-many relationships where the dimension table is the one side. Keep relationships between dimensions minimized and avoid circular relationships. This results in a cleaner power bi semantic model and better performance and usability.
How does partitioning and performance optimization work with a star schema in Power BI?
Partition the fact table in the data model (for example by date column) to improve refresh and query performance, especially with large datasets. Use aggregated tables, proper indexing during ETL, and reduce cardinality in dimension attributes to optimize performance. Microsoft Fabric and Power BI Premium provide additional partitioning and compute options for large scale models.
Can I create a star schema from a single table or a giant fact table?
Yes, you often need to create a star schema from a single table by splitting the giant fact table into a central fact and multiple dimension tables. Extract distinct attribute lists to form dimension tables (customer dimension, product dimension, etc.), create surrogate keys, and replace descriptive columns in the fact table with key values. This transforms a single table into a model that looks like a star and enables better data analysis.
How do I use DAX and the semantic model to get better insights from my star schema?
Use DAX (data analysis expressions) to define calculated measures, time intelligence, and row-level logic that leverages the relationships in your star schema. The power bi semantic model should expose clear measures and hierarchies so business users can build dashboards and complex analytics. Well-modeled dimension tables and a proper fact table make it easier to use DAX effectively and deliver better insights.
🚀 Want to be part of m365.fm?
Then stop just listening… and start showing up.
👉 Connect with me on LinkedIn and let’s make something happen:
- 🎙️ Be a podcast guest and share your story
- 🎧 Host your own episode (yes, seriously)
- 💡 Pitch topics the community actually wants to hear
- 🌍 Build your personal brand in the Microsoft 365 space
This isn’t just a podcast — it’s a platform for people who take action.
🔥 Most people wait. The best ones don’t.
👉 Connect with me on LinkedIn and send me a message:
"I want in"
Let’s build something awesome 👊
Summary
Running The Star Schema Trick All Pros Use means giving your Power BI / data model the structure that performance engines expect — instead of letting it devolve into “digital spaghetti.” In this episode, I explain why flattening everything into a giant table feels easy at first, but drags your reports into slowness and inaccuracy under the hood.
You’ll hear how fact tables and dimension tables each serve distinct roles, how relationships optimize filtering rather than complicate it, and why cleaning your schema is often more powerful than optimizing DAX. By the end, you’ll know how to spot when your model is broken, how to cut it cleanly into facts + dimensions, and how to make your visuals respond instantly rather than crawl.
What You’ll Learn
* What “digital spaghetti” is and why it kills model performance
* The definition and roles of fact tables vs dimension tables
* How to normalize facts and flatten dimensions to align with VertiPaq engine behavior
* Why a proper date table is non-negotiable and how to handle role-playing dates
* Tactics to clean blanks, flag codes, and cryptic attributes before they become slicers
* How to use “junk dimensions” to collect many small flags without bloating the fact
* Best practices to make your schema resilient, performant, and predictable
Full Transcript
Your tangled web of tables isn’t a data model—it’s digital spaghetti. No wonder DAX feels like you’re solving a sudoku puzzle after twelve beers. The good news: cleaning it up pays off fast. With the right design, your visuals respond to filters in seconds, your DAX stops fighting you, and your model finally looks like something you’d want to show your boss.
The trick is a star schema. That means one or more fact tables in the center holding your measures and events, surrounded by dimension tables—the who, what, when, and where. Relationships define the roles, and the engine is built to optimize that structure.
You don’t need a PhD in data warehousing; you just need to untangle the chaos into this simple pattern. For more deep dives, hit m365.show—you’ll want it for your next model.
Now, why does your current report crawl like a floppy drive in 1995 the moment you add a filter? Let’s get into that.
The Digital Spaghetti Problem
Welcome to the heart of the problem: the Digital Spaghetti model. You know the type—a giant flat table packed with every column anyone ever thought was useful. Customer names, job titles, phone numbers, sales amounts, discount codes, the works—all jammed together. It feels fine at first because you can throw visuals at it and see numbers appear. But once you stack slicers, cross filters, and extra pages, the whole thing bogs down. That’s not bad luck, and it’s not Fabric throwing a tantrum. It’s the wrong design.
Think of it like a city built without streets. Every building stacked on top of each other in one giant pile. Sure, you can live there if you’re willing to climb over roofs and windows, but try driving across it efficiently—gridlock. A flattened model does the same thing: it clumps facts and context in the same space, so every query has to crawl through duplicate information before getting to the answer.
Microsoft’s own documentation is clear on this point. The Vertipaq engine running Power BI is optimized for one specific design: dimensions store descriptive context such as customers, dates, or regions, and facts store numeric events like sales, clicks, or costs. When you collapse everything into one giant fact-like table, you force the engine to re-do work on every query. SQLBI calls out exactly why this fails: DAX’s auto-exist behavior can produce incorrect results, and missing combinations of data break relationships that should exist but don’t. In practice, this means your report isn’t just sluggish—it can also be misleading.
A large share of real-world performance problems trace back to this exact modeling choice. Not formulas. Not your GPU. Just chaotic schema design. Flattened models force inefficient query patterns: text values get repeated thousands of times, DAX has to de-duplicate attributes over and over, and filter propagation breaks when dimension logic is buried inside fact rows. That’s why your calculations feel heavy—they’re retracing steps the star schema would handle automatically.
Now, here’s a quick 30-second check to see if you’re stuck in Digital Spaghetti:
First: open your fact table. If you see descriptive text like customer names or region values repeated tens of thousands of times, you’ve got spaghetti.
Second: look at your slicers. If 90% of them are built directly from giant fact table columns instead of small lookup tables, that’s spaghetti too.
Third: ask yourself if you’ve got fact columns that double as static attributes—like a “salon group” typed into transaction rows—even when no visits exist. That right there is spaghetti. One “yes” on these checks doesn’t doom your model, but if you hit all three, you’re running in the wrong direction.
The fix doesn’t happen by blaming DAX. The formulas aren’t broken. What’s broken is the road they’re driving on. When attributes live in fact rows, the engine burns time scanning duplicated text for every query. Star schemas solve this by splitting out those attributes into clean, slim dimension tables. One join, one filter, clean result. No detective work required.
This is why experts keep hammering the same advice: expose attributes through dimensions, hide columns in fact tables, and respect the separation between context and numbers. It isn’t academic nitpicking—it’s the design that prevents your report from collapsing in front of the VP. Get the model shape right, and suddenly the engine works with you instead of against you.
Bottom line: what looks like a harmless shortcut—a single huge table—creates a brittle, sluggish model that makes everything harder. Recognizing that the problem is structural is the first real win. Once you see the spaghetti for what it is, draining it becomes the logical next move.
And draining it starts with a sort: deciding what belongs in facts and what belongs in dimensions. That single choice—the first clean cut—is what shifts you from chaos to clarity.
Facts vs Dimensions: The First Sorting Hat
So here’s where the Sorting Hat comes in: deciding what goes into facts and what belongs in dimensions. It might feel like a simple split, but it’s the first real test of whether your model is going to work or implode. Facts are the measurements—how many, how much, how often. Dimensions are the descriptions—the who, what, when, and where. Keep those roles clean, and suddenly filters know exactly where to go instead of trying to squeeze through gridlock.
The general rule is blunt: dimensions describe, facts measure. A fact table is just measurable stuff—transactions, sales amounts, counts of visits. Dimensions hold your lookups: Customers, Products, Dates, Regions. If you jam them all into one table, you get nothing but duplicated values, heavy filtering, and DAX errors that feel like gremlins.
Take relationships: every one-to-many relationship in Power BI tells you who’s who. The “one” side is always the dimension. The “many” side is always the fact. That simple distinction saves you from guessing. Dimensions provide the clean list, facts reference them. If your so-called dimension sits on the “many” end, it’s not a dimension—it’s another fact with identity issues. And if your would-be dimension doesn’t have a unique column? Fine. Build one. Power Query has “Add Index Column.” That’s your surrogate key. No excuses, no drama—just give the engine something unique to latch onto and move on.
What happens if you don’t respect that split? SQLBI has a classic example: a beauty salon dataset. At first, people dumped salon group information straight into the Visits fact table. Looked convenient—until slicing by gender or job title produced missing totals. Why? Because auto-exist logic in DAX couldn’t handle the missing combinations. Key groups didn’t exist in the fact table at all, so filters silently dropped numbers. The fix was obvious once you see it: build real dimension tables for Gender, Job, and Salon. Then adjust the measure to operate on those. Suddenly, the totals matched reality, filters worked, and ghost results disappeared. That’s the power of getting the fact/dimension boundary right.
Another pitfall: stuffing descriptive text straight into your fact table because “it’s already there.” For example, Region repeated half a million times for every transaction. That’s not a lookup—it’s spam. Every time you slice on Region, the model wastes cycles mashing those rows down into a unique list. Instead, throw Region into a dimension table, store each region once, and let the join handle the rest. That’s cleaner, faster, and accurate.
Best practice here is non-negotiable: hide descriptive columns in the fact table and expose attributes only through the dimension tables. You will thank yourself later when your report actually slices cleanly. Slicers should point to dimensions, not bloated fact text fields. Get lazy, and you’ll be back to watching spinners while DAX cries in the background.
If you want a mental image: facts are the receipts, dimensions are the catalog. Receipts don’t carry full product names, addresses, or job titles—they just reference IDs and amounts. The catalog—your dimension—stores the product info once and for all. Mix them up and you’re basically stapling the entire IKEA manual onto every receipt, over and over. That’s what kills performance.
Even Microsoft’s docs repeat this like gospel: dimensions are the single source of truth for lookups. When you follow that, a slicer on Customer or Region works the way you expect—once and cleanly across all related facts. It works not because DAX woke up smarter, but because the schema is finally aligned with how the engine is built to behave.
So the Sorting Hat rule is simple. Facts: your sales, visits, or other measurable events. Dimensions: your customers, products, dates, and regions. Keep them in their lanes. If the “one” side of the relationship can’t stand uniquely, give it a surrogate key. Then hide every descriptive column in your facts and let dimensions carry them. It sounds strict, but the payoff is filters that work, models that load fast, and measures that stop tripping over themselves.
Now that we’ve sorted the cast into facts and dimensions, there’s a twist waiting. Microsoft insists you treat each side differently: slim facts, chunky dimensions. Sounds like a paradox. But there’s a reason for it—and that’s where we’re heading next.
Normalize the Fact, Flatten the Dimension
Normalize the fact, flatten the dimension. That’s the rule Microsoft keeps drilling into us, and once you see it in practice, it makes sense. Facts are meant to stay lean and normalized. Dimensions? They’re meant to carry all the descriptive weight in one flattened place. Get that wrong, and your filters stall out while memory usage balloons.
Start with fact tables. These are your transaction logs—each row an actual event: a purchase, a return, a shipment. What belongs inside? Keys that link to dimensions, plus numeric measures you can aggregate. That’s it. Every time you toss in descriptive fields—like customer names, product categories, or vendor addresses—you’re bloating the table. Think about a sales table with 100 million rows. If you stick the phrase “Blue Running Shoe, Men’s” in there, congratulations, you’ve just written it 100 million times. That’s not modeling—that’s landfill. All that repetition steals storage, slows queries, and forces the engine to grind through useless text.
So the move is normalization. Pull that descriptive data out. Replace it with surrogate keys, then park the real attributes in a dimension table where they only live once. Power Query even gives you a direct button for this: Add Index Column. That index becomes the surrogate key for your dimension. Then you merge that key into the fact table so the relationship is one-to-many, clean and reliable. That’s Microsoft’s own guidance, and it’s the backbone of why facts behave when they’re normalized.
There’s another rule you can’t skip: pick a grain and stick to it. Grain is the detail level of your fact—per transaction, per order line, or per daily rollup. Mixing grains in one table is like throwing metric and imperial units together. Suddenly totals miss, averages skew, and you’re debugging “wrong” numbers forever. Decide the grain when you design the fact, then make sure every row follows it. The result is consistent, predictable queries that won’t surprise you mid-demo.
Dimensions take the opposite treatment: flatten them. In relational databases, you’d normalize dimensions into “snowflakes”—a product table that links to a subcategory table, which links to a category table, which finally links to a department table. That’s how someone gets tenure as a data architect. But in Power BI, that design turns your model into molasses. Why? Because every filter has to drag itself up chains of multiple tables, which increases model size, complicates queries, and forces report authors to leap across three or four lookups just to grab one attribute.
Flattening dimensions fixes that. Denormalize the hierarchy into a single table. A Product dimension includes the product name, brand, subcategory, category—all in one place. A Customer dimension carries region, state, and age group side by side. Reporting becomes simpler, because slicers grab attributes directly without climbing through links. From an author perspective, it’s one clean table instead of five confusing ones. From a performance perspective, it’s fewer joins and faster filter propagation.
That doesn’t mean snowflakes never exist, but treat them like last-resort exceptions. Maybe you’ve inherited a taxonomy that changes daily, or you’ve got shared reference data governed by another system. Fine, snowflake it. But know the trade-off: more joins, more relationships, slower filters, bigger model. Unless governance forces your hand, flatten dimensions and keep life simple.
The receipts-versus-catalog example is still the easiest way to picture this. Your facts are receipts—just IDs, quantities, and amounts, never full descriptions repeated over and over. Your dimensions are the catalog. Each product is listed with its details once, and everything points back. That balance keeps storage light, queries fast, and reports intuitive. Let receipts stay skinny. Let the catalog be thorough.
When you apply this split consistently—normalize the facts, flatten the dimensions—you line up your model with how Vertipaq and DAX were designed to work. Query scans are smaller, slicers resolve instantly, and authors don’t waste half their time hunting keys across lookup chains. That’s not style points. That’s raw performance delivered by schema discipline.
And once your facts and dimensions are behaving, the next challenge becomes obvious. Your numeric measures make sense, your categories filter cleanly, but time itself is still a mess. Without fixing that piece, you can’t even count correctly across months or years.
The Sacred Date Table
Which brings us straight to the most overlooked table in every Power BI model: the Sacred Date Table. People love skipping it because “we already have an OrderDate column.” That shortcut is a trap. A single raw column in a fact table isn’t enough. It leads to inactive relationships, clunky DAX workarounds, and broken time intelligence. If you’ve ever written a period‑to‑date calculation that gave you nonsense, odds are you tried to cheat without a proper date dimension.
Business logic lives on the calendar. Orders, invoices, shipments, churn—it all ties back to time. Microsoft’s docs don’t mince words here: build a dedicated date table. Not optional, not “nice to have.” Required. And building one is dead simple if you know the rules. Start with a continuous range that covers every date your data could touch—from the earliest transactions you care about to the latest forecasted horizon. Don’t patch holes. If you miss a gap, you’ll wonder why a chart skips March like the month never existed.
Next: add a surrogate key so this becomes a real dimension, not just another column. You can use Power Query’s “Add Index Column,” or go with a formatted yyyymmdd key. Either way, give the model a clean “one” side for relationships. That’s the glue that makes star schema queries predictable, instead of wobbling around inactive joins.
Then, stock your date table with every attribute your reports ever slice by. Year, Quarter, Month, Day, MonthName, maybe even flags like IsWeekend or IsWorkingDay. If you rely on raw dates alone, you’ll drag calculations into places they don’t belong. Authoring visuals becomes far easier when those attributes are baked into the dimension. Want a simple slicer on Month Name? It’s already there, spelled out, no hacks required.
Now let’s talk about roles. Facts usually don’t come with one date column—they come with a dozen. OrderDate, ShipDate, DueDate, PaymentDate. Trying to funnel all of those through one “Date” table is the fastest way into USERELATIONSHIP hell. Every time you want to slice on shipping versus ordering, you’re forced to juggle DAX syntax nobody wants to debug. The clean fix is role‑playing date tables. Duplicate the same dimension for each role: one as Order Date, one as Ship Date, one as Delivery Date. Each relationship stays active. Each table gets clear names: ShipYear, OrderYear, InvoiceYear. Suddenly your slicers work cleanly, and your authors stop swearing at the relationship view.
“How many duplicates are we talking?” Just a handful. And no, you shouldn’t worry about storage. Date dimensions are tiny compared to fact tables. Duplicating a few thousand rows of calendar data doesn’t touch the space cost of a hundred million line transactions. It’s cheap insurance that keeps your measures simple and your model sane. Power Query referencing queries are the preferred way to do it: build the master once, then spin off role‑playing copies. If you must, you can also generate them with calculated tables, but referencing queries keep it organized and efficient.
Do it right once and it pays dividends forever. Year‑to‑Date actually computes as Year‑to‑Date. Same‑Period‑Last‑Year isn’t a coin toss. Period‑over‑period comparisons stop breaking mid‑presentation. You don’t need a page of exotic DAX to tell filter context which column you meant—it just works. All because the calendar finally got the respect it deserves.
A date table isn’t glamorous, but it’s the backbone of every reliable report. Skip it, and no amount of clever measures will save you. Build it with a proper range, a surrogate key, and clean role‑playing copies, and you’ll never babysit inactive relationships again.
And once time is under control, the next source of user pain stares you right in the face. Your slicers. Because nothing kills confidence faster than exposing raw blanks, cryptic codes, or “flag_1” fields that only a database admin could love.
Beating Blanks, Flags, and Cryptic Codes
Blanks, flags, and cryptic codes—this is the part no one brags about fixing, but everyone notices when you don’t. You can spend weeks designing the perfect star schema and still watch the whole thing lose credibility if the slicers greet users with “flag_1” instead of something real. At that point, the issue isn’t performance, it’s trust. And people stop trusting fast when reports look like they were built for robots.
The mess comes from the source systems. Old ERPs and CRMs love storing logic as flags, abbreviations, or random codes some DBA thought was brilliant in 1998. Add in missing values—nulls for entire customer segments or blank sales channels—and suddenly your report is littered with confusion. The mistake is letting it flow straight through into visuals. If a VP clicks a drop‑down and sees “0” or “flag_2,” they’re gone. They’ll nod politely and then export raw data to Excel, which means everything you built gets sidelined.
The fix is not yelling at your users until they memorize the code table. It’s cleaning the data before it ever hits the model. Power Query is where this gets solved. Three steps, in order. First, replace nulls with something meaningful. Use “Unknown,” “Other,” or “Not Provided.” That gives gaps a proper label so people understand it’s missing, not broken. Second, decode every system flag into a business‑friendly description. Turn “flag_1” into “Customer Active = Yes.” Turn “M” into “Male.” Turn “F” into “Female.” If you have codes nobody even remembers anymore, document them once and translate them permanently. Third, hide or remove the raw technical columns after you’ve built the replacements. “Cust_Flag” and “Sales_Ind” belong in data plumbing, not front‑end slicers.
This is one of those rare cases where “cosmetic cleanup” is actually risk management. Leave complex codes visible and you guarantee mis‑clicks and wrong assumptions. The HR horror story is classic: some systems use “M” and “F” for gender. One person reads it correctly as Male and Female, another misreads “F” as Friday, and now you’ve got a headcount chart that looks like half your staff vanished on weekends. One small misinterpretation, the board questions the data, and suddenly every insight gets second‑guessed. Making labels human is how you stop that chain reaction.
But what about when you’ve got dozens of tiny flags? Customer Current, Customer Preferred, Newsletter Opt‑In, Loyalty Member, Account Suspended—you name it. Dumping each of those into the fact table turns it into a junk drawer. Every flag repeated across millions of rows, bloating storage and killing clarity. The better pattern here is what’s called a “junk dimension.” Instead of leaving those fragments scattered in facts, you bundle them together. Power Query can generate the full Cartesian product of the valid flag combinations. Give it a surrogate key with “Add Index Column,” then swap those raw flags in your fact table for the single surrogate. Result: facts stay lean, the dimension holds all the descriptive logic, and your slicers suddenly present clean, business‑language options without cluttering the model. This reduces noise, improves performance, and makes maintenance almost effortless.
When people say fix it once, this is the case study. Shape it right in Power Query, and downstream reports enforce the new clarity automatically. Every new visual, every slicer, every page—human labels by default, no extra clean‑up required. Compare that to firefighting the same data confusion every time an analyst builds a new dashboard. Do the heavy lifting once upstream.
None of these steps are optional. Replace the blanks, decode the flags, label attributes in plain business terms, and hide the system plumbing. This isn’t polish. It’s the difference between a report users believe and one they quietly bypass. When slicers match the language of the business, people stop questioning the structure and start making decisions.
And if you want to shortcut the trial‑and‑error of figuring this out, there’s a free checklist waiting at m365.show. It lays out these exact transforms so you don’t miss them, and MVPs walk through the live fixes at M365.Show if you’d rather watch instead of read.
Once you’ve beaten the blanks, flags, and cryptic codes into shape, the bigger picture shows itself. Clean models aren’t theory—they’re the guardrail between straightforward, scalable DAX and the chaos that grinds reports to a halt when the execs are watching.
Conclusion
So here’s the wrap-up. Star schema isn’t decoration, it’s the backbone. Why? Because it cleanly separates filtering and grouping in dimensions from summarizing in facts—the exact structure Vertipaq and DAX were built for. That’s why reports run faster and modeling actually stays sane.
If you only remember three things from this video, make it these: one, identify facts versus dimensions; two, normalize facts and flatten dimensions; three, give yourself a proper date table and clean up flags before they hit a slicer. Nail those, and your model will carry you for years.
Want the checklist? Subscribe to the newsletter at m365.show. And make sure to follow the M365.Show LinkedIn page for livestreams with MVPs who’ve actually fixed this stuff in the wild. Ahh, and Subscribe for the Podcast now!
This is a public episode. If you'd like to discuss this with other subscribers or get access to bonus episodes, visit m365.show/subscribe

Founder of m365.fm, m365.show and m365con.net
Mirko Peters is a Microsoft 365 expert, content creator, and founder of m365.fm, a platform dedicated to sharing practical insights on modern workplace technologies. His work focuses on Microsoft 365 governance, security, collaboration, and real-world implementation strategies.
Through his podcast and written content, Mirko provides hands-on guidance for IT professionals, architects, and business leaders navigating the complexities of Microsoft 365. He is known for translating complex topics into clear, actionable advice, often highlighting common mistakes and overlooked risks in real-world environments.
With a strong emphasis on community contribution and knowledge sharing, Mirko is actively building a platform that connects experts, shares experiences, and helps organizations get the most out of their Microsoft 365 investments.








