Site icon Phil Seamark on DAX

The Impact of Primary Keys on DAX Query Performance in Power BI

When writing DAX queries, performance tuning often comes down to small design decisions that have big consequences. One such decision is whether to include Primary Key columns from Dimension tables in your SUMMARIZECOLUMNS statements. This is particularly important when those Dimension tables use DUAL or IMPORT storage modes.

This article explains why doing so can lead to inefficient query plans. It describes what happens under the hood. It also shows how to avoid this common pitfall.

The Problem: From SPARSE to DENSE Queries

Including a Primary Key as a group-by column in a SUMMARIZECOLUMNS statement changes the query behaviour. Instead of operating as a SPARSE query, which processes only combinations that exist in the data, the query becomes DENSE.

What Does This Mean?

This shift introduces an outer join step in the query plan, which:

Visualising the impact

Why Does This Hurt Performance?

In large models, this can lead to significant slowdowns and poor scalability.

Example: Bad vs Good

Bad Approach

Including the Primary Key:

EVALUATE
SUMMARIZECOLUMNS (
    DimCustomer[CustomerKey],  // Primary Key from Dimension
    DimCustomer[Country],
    "Sales", SUM ( Sales[Amount] )
)

Better Approach

Exclude the Primary Key:

EVALUATE
SUMMARIZECOLUMNS (
    DimCustomer[Country],
    "Sales", SUM ( Sales[Amount] )
)

By removing the Primary Key, the query avoids unnecessary outer joins. It also prevents redundant iterations. This results in a leaner, faster execution plan.

Recent example

I helped on a recent example where a reasonably clean set of Server Timings was shared. The query took 38 seconds despite spending only a tiny part of that time collecting data. The presence of the scan at line 8 shows a “Dimension Scan” that has no aggregate task (SUM, MAX, AVG etc.). The output of this event is an intermediary table with 831,278 rows to be iterated over. The large yellow section in the Timeline chart suggests the amount of time spent on the DENSE loop.

Best Practices

Do not include Primary Key columns from Dimension tables in SUMMARIZECOLUMNS unless absolutely necessary. Group by attributes relevant to your calculation, not identifiers. Let the engine optimise for SPARSE queries, which only process combinations where data exists.

Create a cloned version of the column in the dimension table if need. This new column can carry the value from the PK column. Use this column in your grouping set in place of the PK column.

Hide ALL columns in your semantic model that get used either side of any relationship.

Summary

A Primary Key column gets used on the axis of a Power BI Visual. These columns are included as group-by columns in SUMMARIZECOLUMNS. This inclusion can turn an efficient SPARSE query into a costly DENSE query. This results in extra storage engine events, wasted resources, and slower performance. Avoid this by grouping only on meaningful attributes.

5 1 vote
Article Rating
Exit mobile version