πŸ”’ Guided

Pre-launch preview. Authorised access only.

Incorrect code

Guided by A Guide to Cloud
Explore AB-900 AI-901
Guided DP-600 Domain 3
Domain 3 β€” Module 7 of 8 88%
28 of 29 overall

DP-600 Study Guide

Domain 1: Maintain a Data Analytics Solution

  • Workspace Access Controls
  • Row-Level & Object-Level Security
  • Sensitivity Labels & Endorsement
  • Git Version Control in Fabric
  • Deployment Pipelines: Dev β†’ Test β†’ Prod
  • Impact Analysis & Dependencies
  • XMLA Endpoint & Reusable Assets

Domain 2: Prepare Data

  • Microsoft Fabric: The Big Picture Free
  • Lakehouses: Your Data Foundation Free
  • Warehouses in Fabric Free
  • Choosing the Right Data Store Free
  • Data Connections & OneLake Catalog
  • Shortcuts & OneLake Integration
  • Ingesting Data: Dataflows Gen2 & Pipelines
  • Star Schema Design Free
  • SQL Objects: Views, Functions & Stored Procedures
  • Transforming Data: Reshape & Enrich
  • Data Quality & Cleansing
  • Querying with SQL
  • Querying with KQL
  • Querying with DAX

Domain 3: Implement and Manage Semantic Models

  • Semantic Models: Storage Modes
  • Relationships & Advanced Modeling
  • DAX Essentials: Variables & Functions
  • Calculation Groups & Field Parameters
  • Large Models & Composite Models
  • Direct Lake Mode
  • DAX Performance Optimization
  • Incremental Refresh

DP-600 Study Guide

Domain 1: Maintain a Data Analytics Solution

  • Workspace Access Controls
  • Row-Level & Object-Level Security
  • Sensitivity Labels & Endorsement
  • Git Version Control in Fabric
  • Deployment Pipelines: Dev β†’ Test β†’ Prod
  • Impact Analysis & Dependencies
  • XMLA Endpoint & Reusable Assets

Domain 2: Prepare Data

  • Microsoft Fabric: The Big Picture Free
  • Lakehouses: Your Data Foundation Free
  • Warehouses in Fabric Free
  • Choosing the Right Data Store Free
  • Data Connections & OneLake Catalog
  • Shortcuts & OneLake Integration
  • Ingesting Data: Dataflows Gen2 & Pipelines
  • Star Schema Design Free
  • SQL Objects: Views, Functions & Stored Procedures
  • Transforming Data: Reshape & Enrich
  • Data Quality & Cleansing
  • Querying with SQL
  • Querying with KQL
  • Querying with DAX

Domain 3: Implement and Manage Semantic Models

  • Semantic Models: Storage Modes
  • Relationships & Advanced Modeling
  • DAX Essentials: Variables & Functions
  • Calculation Groups & Field Parameters
  • Large Models & Composite Models
  • Direct Lake Mode
  • DAX Performance Optimization
  • Incremental Refresh
Domain 3: Implement and Manage Semantic Models Premium ⏱ ~13 min read

DAX Performance Optimization

Slow dashboards lose users. Learn how to identify and fix DAX performance issues using DAX Studio, Performance Analyzer, and proven optimization patterns.

Why DAX performance matters

β˜• Simple explanation

Think of a slow dashboard like a slow restaurant.

If every report visual takes 10 seconds to load, users stop using the dashboard. They go back to their spreadsheets. All the work you put into building the model is wasted.

DAX performance is about making measures calculate as fast as possible. The three levers: (1) write efficient DAX, (2) design the model for the engine, and (3) use the right tools to find bottlenecks.

DAX performance optimization involves reducing the time the Analysis Services engine takes to evaluate measures and queries. The main factors: storage engine queries (how data is read from VertiPaq or Direct Lake), formula engine calculations (how DAX expressions are evaluated), and report design (how many queries a visual generates). Tools: DAX Studio (query analysis), Performance Analyzer (visual timing), and VertiPaq Analyzer (model size).

The two engines

Every DAX query is processed by two engines:

EngineWhat It DoesSpeed
Storage Engine (SE)Reads data from VertiPaq (or Direct Lake/DirectQuery). Handles simple filters and aggregations.Very fast β€” in-memory scans
Formula Engine (FE)Evaluates complex DAX expressions (iterators, nested CALCULATE, cross-table calculations).Slower β€” single-threaded, row-by-row

Optimization goal: Push as much work as possible to the Storage Engine. Minimize Formula Engine usage.

Common DAX performance problems

1. Unnecessary iterators

// SLOW: Iterator processes every row
Bad Measure = SUMX(Sales, IF(Sales[Category] = "Grocery", Sales[Amount], 0))

// FAST: Filter then aggregate (Storage Engine handles it)
Good Measure = CALCULATE(SUM(Sales[Amount]), Sales[Category] = "Grocery")

Why: SUMX with IF forces the Formula Engine to evaluate every row. CALCULATE with a filter pushes the work to the Storage Engine.

2. Nested CALCULATE

// SLOW: Redundant outer CALCULATE β€” unnecessary context transition
Bad YoY =
CALCULATE(
    CALCULATE(
        [Revenue],
        SAMEPERIODLASTYEAR(Dates[Date])
    )
) - [Revenue]

// FAST: Variables + single CALCULATE
Good YoY =
VAR PYRevenue = CALCULATE([Revenue], SAMEPERIODLASTYEAR(Dates[Date]))
VAR CurrentRevenue = [Revenue]
RETURN CurrentRevenue - PYRevenue

3. Too many visuals on one page

Each visual generates one or more DAX queries. A page with 30 visuals generates 30+ queries. Optimization:

  • Reduce visual count per page (target 10-15)
  • Use report page tooltips instead of embedding details
  • Lazy-load visuals below the fold

4. High-cardinality columns in visuals

Placing a column with millions of unique values on an axis forces the engine to process millions of groups. Use aggregated tables or limit the axis to top N values.

Tools for performance analysis

Start with Performance Analyzer (easy), go deeper with DAX Studio (advanced)
ToolWhat It ShowsWhen to Use
Performance AnalyzerTime per visual: DAX query time, direct query time, render timeQuick check β€” which visuals are slow?
DAX StudioServer Timings: SE vs FE split, query plan, row countDeep analysis β€” why is this measure slow?
VertiPaq AnalyzerModel size: table sizes, column sizes, relationship sizesModel design β€” which tables/columns consume the most memory?
Query DiagnosticsDirectQuery: SQL queries generated, query duration, row countDirectQuery performance β€” are source queries efficient?

DAX optimization patterns

Pattern 1: Variables (always use)

// Variables prevent repeated evaluation
Revenue YoY % =
VAR Current = [Total Revenue]
VAR PY = CALCULATE([Total Revenue], SAMEPERIODLASTYEAR(Dates[Date]))
RETURN
    DIVIDE(Current - PY, PY)

Pattern 2: CALCULATE instead of iterator + IF

// Instead of SUMX with IF
Grocery Revenue =
CALCULATE(
    [Total Revenue],
    Products[Category] = "Grocery"
)

Pattern 3: KEEPFILTERS for intersecting filters

// KEEPFILTERS preserves existing filters instead of overriding
High Value Grocery =
CALCULATE(
    [Total Revenue],
    KEEPFILTERS(Products[Category] = "Grocery"),
    Sales[Amount] > 100
)

Pattern 4: Avoid DISTINCTCOUNT on large columns

// SLOW on high-cardinality columns
Unique Customers = DISTINCTCOUNT(Sales[CustomerID])

// FASTER: Pre-aggregate in the data layer
-- Create a customer count column in the aggregate table
πŸ’‘ Scenario: Anita optimises slow dashboards

Anita at FreshCart’s sales dashboard takes 25 seconds to load. She uses Performance Analyzer and finds:

  • The β€œRevenue by Product” matrix takes 12 seconds (shows 5,000 products)
  • The β€œYoY Growth” card takes 8 seconds

Her fixes:

  1. Product matrix: Add a Top 50 filter (reduce from 5,000 to 50 products)
  2. YoY Growth: Rewrite with VAR to prevent double evaluation
  3. Page design: Move 10 detail visuals to a drill-through page (reduce from 25 to 15 visuals)

Result: load time drops from 25 seconds to 3 seconds.

Question

What are the two engines that process DAX queries?

Click or press Enter to reveal answer

Answer

1. Storage Engine (SE) β€” reads data from VertiPaq/Direct Lake. Handles simple filters and aggregations. Multi-threaded, very fast. 2. Formula Engine (FE) β€” evaluates complex DAX expressions. Single-threaded, slower. Goal: push as much work to SE as possible.

Click to flip back

Question

Why is CALCULATE(SUM(), filter) faster than SUMX(table, IF())?

Click or press Enter to reveal answer

Answer

CALCULATE with a filter pushes the work to the Storage Engine (optimised for filtered aggregation). SUMX with IF forces the Formula Engine to evaluate every row individually (single-threaded). The Storage Engine path is orders of magnitude faster on large tables.

Click to flip back

Question

Name three tools for analyzing DAX performance.

Click or press Enter to reveal answer

Answer

1. Performance Analyzer (in Power BI Desktop) β€” shows per-visual timing. 2. DAX Studio β€” deep query analysis with Storage Engine vs Formula Engine split. 3. VertiPaq Analyzer β€” model size analysis showing table/column memory usage.

Click to flip back

Knowledge Check

Anita at FreshCart has a measure: SUMX(Sales, IF(Sales[StoreType] = 'Metro', Sales[Amount], 0)). The measure is slow on a 500M-row fact table. Which rewrite is faster?

Knowledge Check

A Power BI report page has 30 visuals and takes 45 seconds to load. Performance Analyzer shows each visual takes 1-2 seconds. What is the most effective optimization?

🎬 Video coming soon


Next up: Incremental Refresh β€” refresh only what changed, keeping your semantic models fast and efficient.

← Previous

Direct Lake Mode

Next β†’

Incremental Refresh

Guided

I learn, I simplify, I share.

A Guide to Cloud YouTube Feedback

© 2026 Sutheesh. All rights reserved.

Guided is an independent study resource and is not affiliated with, endorsed by, or officially connected to Microsoft. Microsoft, Azure, and related trademarks are property of Microsoft Corporation. Always verify information against Microsoft Learn.