Understand how to write efficient DAX formulas to improve Power BI report performance.
Optimizing DAX queries in Power BI - Dashboard Guide
| OrderID | Product | Category | Quantity | UnitPrice | OrderDate |
|---|---|---|---|---|---|
| 1001 | Notebook | Stationery | 5 | 2.5 | 2024-01-10 |
| 1002 | Pen | Stationery | 10 | 1.2 | 2024-01-11 |
| 1003 | Chair | Furniture | 2 | 45 | 2024-01-12 |
| 1004 | Desk | Furniture | 1 | 120 | 2024-01-13 |
| 1005 | Marker | Stationery | 7 | 1.5 | 2024-01-14 |
| 1006 | Bookcase | Furniture | 1 | 80 | 2024-01-15 |
- KPI Card: Total Sales
Formula:Total Sales = SUMX(Sales, Sales[Quantity] * Sales[UnitPrice])
Result: 5*2.5 + 10*1.2 + 2*45 + 1*120 + 7*1.5 + 1*80 = 12.5 + 12 + 90 + 120 + 10.5 + 80 = 325 - KPI Card: Total Quantity Sold
Formula:Total Quantity = SUM(Sales[Quantity])
Result: 5 + 10 + 2 + 1 + 7 + 1 = 26 - Bar Chart: Sales by Category
Formula for measure:Sales by Category = SUMX(FILTER(Sales, Sales[Category] = SELECTEDVALUE(Sales[Category])), Sales[Quantity] * Sales[UnitPrice])
Values:
- Stationery: (5*2.5)+(10*1.2)+(7*1.5) = 12.5 + 12 + 10.5 = 35
- Furniture: (2*45)+(1*120)+(1*80) = 90 + 120 + 80 = 290 - Table: Sales Details
Columns: OrderID, Product, Category, Quantity, UnitPrice, Total Sale
Calculated Column Formula:Total Sale = Sales[Quantity] * Sales[UnitPrice]
Shows each order's total sale value. - Optimized Measure: Total Sales Optimized
Formula:Total Sales Optimized = SUMX(Sales, Sales[Quantity] * Sales[UnitPrice])
Note: Using SUMX directly on the Sales table is efficient here because it avoids unnecessary FILTER or CALCULATE functions.
+----------------------+----------------------+ | Total Sales | Total Quantity Sold | | (KPI) | (KPI) | +----------------------+----------------------+ | | | Sales by Category (Bar Chart) | | | +----------------------------------------------+ | | | Sales Details (Table) | | | +----------------------------------------------+
Adding a slicer for Category filters all components:
- KPI cards update to show totals only for the selected category.
- Bar chart highlights the selected category's sales.
- Sales details table shows only orders from the selected category.
This interactivity helps users focus on specific product categories and see optimized DAX measures update instantly.
If you add a filter for Category = Furniture, which components update and what are their new values?
- Total Sales: 290
- Total Quantity Sold: 4 (2+1+1)
- Sales by Category Bar Chart: Only Furniture bar shows 290, Stationery bar is hidden.
- Sales Details Table: Shows only orders 1003, 1004, 1006.
Practice
What is a simple way to improve the performance of a DAX query in Power BI?
SUM(Sales[Amount]) is slow. What should you do?
Solution
Step 1: Understand the role of variables in DAX
Variables store intermediate results to avoid repeated calculations, making queries faster.Step 2: Apply variables to the example
Using variables inSUM(Sales[Amount])can reduce repeated scans and improve speed.Final Answer:
Use variables to store intermediate results -> Option DQuick Check:
Variables improve performance [OK]
- Adding unnecessary columns slows down queries
- Using complex nested IFs increases calculation time
- Ignoring filters can cause large data scans
Which of the following is the correct syntax to define a variable in a DAX measure?
Measure = ?Solution
Step 1: Recall DAX variable syntax
DAX usesVARto declare variables andRETURNto output the result.Step 2: Match syntax with options
Measure = VAR Total = SUM(Sales[Amount]) RETURN Total correctly usesVAR Total = SUM(Sales[Amount]) RETURN Total.Final Answer:
Measure = VAR Total = SUM(Sales[Amount]) RETURN Total -> Option BQuick Check:
VAR and RETURN are correct DAX keywords [OK]
- Using LET or DEFINE instead of VAR
- Forgetting RETURN keyword
- Using SET or OUTPUT which are not DAX keywords
Consider this DAX measure:
Measure =
VAR FilteredSales = FILTER(Sales, Sales[Region] = "West")
RETURN SUMX(FilteredSales, Sales[Amount])What is the main performance issue with this measure?
Solution
Step 1: Analyze FILTER and SUMX behavior
FILTER creates a filtered table of Sales where Region is "West". SUMX iterates over this filtered table.Step 2: Understand performance impact
If Sales is large, creating and iterating over a filtered table can be slow. Better to filter early or use CALCULATE with SUM.Final Answer:
FILTER creates a filtered table and SUMX iterates over it, which can be slow if Sales is large -> Option AQuick Check:
FILTER + SUMX on large tables can slow queries [OK]
- Thinking SUMX iterates original table, not filtered
- Assuming FILTER before SUMX is always fast
- Ignoring table size impact on performance
Identify the error in this DAX measure that aims to optimize performance:
Measure =
VAR TotalSales = SUM(Sales[Amount])
RETURN
CALCULATE(TotalSales, FILTER(Sales, Sales[Region] = "East"))Solution
Step 1: Check variable type and usage
TotalSales = SUM(Sales[Amount]) is a scalar value computed in the original filter context.Step 2: Analyze CALCULATE arguments
CALCULATE(TotalSales, FILTER(Sales, Sales[Region]="East")) is syntactically valid, but since TotalSales is a pre-computed scalar, the modified filter context does not re-evaluate it. It returns the unfiltered total instead of East sales, defeating the performance optimization goal for filtered calculation.Final Answer:
TotalSales is a scalar evaluated outside CALCULATE, so the filter does not apply -> Option CQuick Check:
Scalar variable used incorrectly with CALCULATE filter [OK]
- Thinking CALCULATE re-evaluates scalar variables in new context
- Thinking FILTER inside CALCULATE is always slow
- Not distinguishing scalar vs table types
You want to optimize a DAX measure that calculates total sales for the current year only. Which approach is best for performance?
Option 1:
Measure = CALCULATE(SUM(Sales[Amount]), FILTER(Sales, YEAR(Sales[Date]) = YEAR(TODAY())))
Option 2:
Measure = CALCULATE(SUM(Sales[Amount]), Sales[Date].[Year] = YEAR(TODAY()))Solution
Step 1: Compare FILTER vs direct column filter
Option 1 uses FILTER which scans row by row, applying YEAR function, which is slow.Step 2: Understand column filter advantage
Option 2 uses a direct filter on the date column's Year attribute, which is faster because it uses existing column indexing and avoids row-by-row evaluation.Final Answer:
Option 2 is better because it uses column filter, not row filter -> Option AQuick Check:
Use column filters over FILTER for better speed [OK]
- Using FILTER with row context unnecessarily
- Assuming FILTER is always faster
- Ignoring built-in column filters
Ready to prove it?
Pass the test and this pattern moves unknown
