Category Archives: DAX

Include post related to DAX (Data Analysis Expressions)

Analysis on performance comparison between DAX and MDX

Once I was asked to find out reason for difference in Performance for DAX and MDX on Tabular Model. For that i went through many links, post and ebook materials. Below are the consolidated observations.

Query Execution of DAX and MDX:

  1. We need to understand high level query execution plan first for DAX or MDX in Tabular Model. Below screenshot explain the same (for any query on Tabular Model):
  2. We cannot find any difference for the MDX and DAX query execution as per above figure.
  3. Difference starts with transform of query from In-Memory Query mode to xVelocity Engine. Below screenshot shows how:Note: MDX is not working on DirectQuery mode.
  4. Execution of queries is done as explained below:
    1. When a DAX query is sent to a Tabular Model, it generate DAX query plan and that is transformed into commands sent to xVelocity Engine.
    2. MDX query is analysed by the MDX Formula Engine, which calls the DAX Formula Engine to solve DAX measures (calculated measures in Tabular model) and generates a query plan that performs requests to the xVelocity Storage Engine.
  5. Thus, MDX query is not converted into an equivalent DAX query, it generates one or more commands to the DAX Formula Engine and then to the xVelocity Storage Engine in order to retrieve values and evaluate the DAX measures it require.
  6. So even when same result is given by DAX and MDX (i.e. when we call it DAX equivalent to MDX), different internal operations can be performed with different performances.
  7. About the query plan, each time when the DAX Formula Engine is called to evaluate a DAX expression, a pair of DAX Query Plan events are generated (i.e. a logical plan event and a physical plan event, but let not discuss this in detail. Detailed information can be viewed here).
    But an MDX query may produce any number of pairs of events depending on how many times the MDX Formula Engine has to call into the DAX Formula Engine (for DAX measure as explained above).
  8. Both MDX and DAX Formula engine perform single threaded operations
  9. xVelocity engine can work on multi-threaded operation. So from above two points, it’s clear to push as much as request on xVelocity engine rather than Formula Engines. I think it will increase performance and it depends upon simpler queries. As the complexity of queries will increase, Formula Engine will be more busy than xVelocity.

From above discussion points, I tried to consolidate it as:

  1. There is no direct way to say completely that DAX is better than MDX in performance or vice versa.
  2. As MDX query uses DAX Formula engine to solve DAX measures, it may effect performance in any of two scenarios:
    1. If measure involve complex logic
    2. If many measures are called together (Refer point 6)
  3. Huge data will not matter in performance, it will be time of converting DAX measure for MDX query by DAX Formula Engine. (Refer point 10)

Convert MDX into DAX Part3

Few more functions to add flexibility to your DAX queries like MDX.


  • We usually come across reporting requirement where a fix format of data. We start looking for different possible FORMAT which can make our task easy.

    FORMAT(<Value to be formatted>,<Format Pattern>)

    It’s easily understandable what this function will do but need to figure what possibilities it can give us.Example:

    ('Internet Sales'
    ,"Sales Amount",FORMAT('Internet Sales'[Internet Total Sales],"Currency")
    Result is:

    Here Currency format gives $ sign, Thousand separator and 2 decimal specification.

    So there is a list of these formats and this link will be best place to get other possible format. But question arise for user defined patterns.

    So below is some part of introduction to most common characters used with FORMAT function to get different results:

    0 Displays 0 or number in the position assigned
    # Displays nothing or number in position assigned
    . Represent decimal place. We use different combination of 0s and #s to left and 0s to right to get formatted values in decimal places
    % First multiplies the number with 100 and display symbol % to the right of the number
    , Used to show thousand separators with the combination of 0s and #s. We can define multiple scaling using different places of separators.
    : Time separator
    $ Used at extreme left of numbers to represent currency. Similarly + and – symbol can be sued.
    \ Displays next character whatever it is. For the character we can use in normal formatting like “, \, /, ., , etc.

    Examples can be
    FORMAT(“123.569”, “$#,##0”); FORMAT(“123.569”, “#,##0”); FORMAT(“123.569”, “#0.00%”) etc.


  • This function does two things:
    a)      Order the result set obtained from Tabular Expressions (Descending or Ascending  order)
    b)      Give rows from the Top of resultOne drawback here, most of the times it doesn’t show the final top result in order of descending. We need to explicitly do ORDER BY.

    TOPN(<number of rows required>, <table or tabular expression>, <orderBy expression>, <Order (0 or 1)>)

    Order argument is option with value
    0: Default, descending order of Order By Expression
    1: ascending order of Oder By Expression
    Required top 10 State on the basis of Internet Sales Amount in MDX.

    SELECT {[Measures].[Internet Total Sales]} ON 0
    {[Geography].[State Province Name].[State Province Name].MEMBERS},
    [Measures].[Internet Total Sales], DESC)  ON 1
    FROM [AdventureWorks_Test]

    Same result set in DAX:

    'Internet Sales'
    ,'Geography'[State Province Name]
    ,"Sales Amount",'Internet Sales'[Internet Total Sales]
    ,'Internet Sales'[Internet Total Sales]
    ORDER BY 'Internet Sales'[Internet Total Sales] DESC

    Last ORDER BY in DAX query to arrange top 10 States obtained by query in Descending order of Sales Amount.