Analysis Services · Power Query

Analysing SSAS Extended Event Data With Power Query: Part 1

The other day, while I was reading this post by Melissa Coates, I was reminded of the existence of extended events in SSAS. I say ‘reminded’ because although this is a subject I’ve blogged about before, I have never done anything serious with extended events because you can get the same data from Profiler much more easily, so I had pretty much forgotten about them. But… while Profiler is good, it’s a long way from perfect and there’s a lot of information that you can get from a trace that is still very hard to analyse. I started thinking: what if there was a tool we could use to analyse the data captured by extended events easily? [Lightbulb moment] Of course, Power Query!

I’m not going to go over how to use Extended Events in SSAS because the following blog posts do a great job already:

You may also want to check out these (old, but still relevant) articles on performance tuning SSAS taken from the book I co-wrote with Marco and Alberto, “Expert Cube Development”:

What I want to concentrate on in this series of posts is how to make sense of this data using Power BI in general and Power Query in particular. The first step is to be able to load data from the .xel file using Power Query, and that’s what this post will cover. In the future I want to explore how to get at and use specific pieces of text data such as that given by the Query Subcube Verbose, Calculation Evaluation and Resource Usage events, and to show how this data can be used to solve difficult performance problems. I’m only going to talk about SSAS Multidimensional, but of course a lot of what I show will be applicable (or easily adapted to) Tabular; I guess you could also do something similar for SQL Server Extended Events too. I’m also going to focus on ad hoc analysis of this data, rather than building a more generic performance monitoring solution; the latter is a perfectly valid thing to want to build, but why build one yourself when companies like SQL Sentry have great tools for this purpose that you can buy off the shelf?

Anyway, let’s get on. Here’s a Power Query function that can be used to get data from one or more .xel files generated by SSAS:

[sourcecode language=”text” padlinenumbers=”true”]
(servername as text,
initialcatalog as text,
filename as text)
as table =>
//Query the xel data
Source = Sql.Database(servername,
object_name, event_data, file_name
FROM sys.fn_xe_file_target_read_file ( ‘"
& filename & "’, null, null, null )"]),
//Treat the contents of the event_data column
//as XML
ParseXML = Table.TransformColumns(Source,
{{"event_data", Xml.Tables}}),
//Expand that column
Expandevent_data = Table.ExpandTableColumn(ParseXML,
{"Attribute:timestamp", "data"},
//A function to tranpose the data held in the
// column
GetAttributeData = (AttributeTable as table) as table =>
RemoveTextColumn = Table.RemoveColumns(AttributeTable,
SetTypes = Table.TransformColumnTypes(RemoveTextColumn ,
{{"value", type text}, {"Attribute:name", type text}}),
TransposeTable = Table.Transpose(SetTypes),
ReverseRows = Table.ReverseRows(TransposeTable),
PromoteHeaders = Table.PromoteHeaders(ReverseRows)
//Use the function above
ParseAttributeData = Table.TransformColumns(Expandevent_data,
{"", GetAttributeData})


This function can be thought of as the starting point for everything else: it allows you to load the raw data necessary for any SSAS performance tuning work. Its output can then, in turn, be filtered and transformed to solve particular problems.

The function takes three parameters:

  • The name of a SQL Server relational database instance – this is because I’m using sys.fn_exe_file_target_read_file to actually read the data from the .xel file. I guess I could try to parse the binary data in the .xel file, but why make things difficult?
  • The name of a database on that SQL Server instance
  • The file name (including the full path) or pattern for the .xel files

The only other thing to mention here is that the event_data column contains XML data, which of course Power Query can handle quite nicely, but even then the data in the XML needs to be cleaned and transposed before you can get a useful table of data. The GetAttributeData function in the code above does this cleaning and transposing but, when invoked, the function still returns an unexpanded column called as seen in the following screenshot:


There are two reasons why the function does not expand this column for you:

  1. You probably don’t want to see every column returned by every event
  2. Expanding all the columns in a nested table, when you don’t know what the names of these columns are, is not trivial (although this post shows how to do it)

Here’s an example of how the function can be used:

[sourcecode language=”text”]
//Invoke the GetXelData function
Source = GetXelData(
"adventure works dW",
//Only return Query End events
#"Filtered Rows" = Table.SelectRows(Source,
each ([object_name] = "QueryEnd")),
//Expand Duration and TextData columns
#"Expand" = Table.ExpandTableColumn(
#"Filtered Rows", "",
{"Duration", "TextData"},
//Set some data types
#"Changed Type" = Table.TransformColumnTypes(
{{"event_data.Attribute:timestamp", type datetime},
{"", Int64.Type}}),
//Sort by timestamp
#"Sorted Rows" = Table.Sort(#"Changed Type",
{{"event_data.Attribute:timestamp", Order.Ascending}}),
//Add an index column to identify each query
#"Added Index" = Table.AddIndexColumn(#"Sorted Rows", "Query Number", 1, 1),
//Remove unwanted columns
#"Removed Columns" = Table.RemoveColumns(#"Added Index",
{"object_name", "file_name"})
#"Removed Columns"


All that’s happening here is that the function is being called in the first step, Source, and then I’m filtering by the Query End event, expanding some of the columns in and setting column data types. You won’t need to copy all this code yourself though – you just need to invoke the function and then expand the column to reveal whatever columns you are interested in. When you run a query that calls this function for the first time, you may need to give Power Query permission to connect to SQL Server and also to run a native database query.

Here’s an example PivotChart showing query durations built from this data after it has been loaded to the Excel Data Model:

Not very useful, for sure, but in the next post you’ll see a more practical use for this function.

You can download the sample workbook for this post here.

6 thoughts on “Analysing SSAS Extended Event Data With Power Query: Part 1

  1. This is a good article. Today I have the same task. But I cannot use the functin (sys.fn_xe_file_target_read_file). And you mantioned about parse XEL file as binary, can you get me some ideas how to do it. Because when I try to call Binary.ToText or Text.FromBinary a have some places with a readable text and a lot of places with unreadable characters with different encodings

Leave a ReplyCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.