{"id":104500,"date":"2024-11-07T23:37:57","date_gmt":"2024-11-07T23:37:57","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=104500"},"modified":"2024-11-07T23:37:58","modified_gmt":"2024-11-07T23:37:58","slug":"analyzing-kusto-query-history-in-fabric","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/analyzing-kusto-query-history-in-fabric\/","title":{"rendered":"Analyzing Kusto Query History in Fabric"},"content":{"rendered":"<p>We can consume a Kusto database in Fabric from many different places: Notebooks, semantic models, real time dashboards and more. Kusto register all queries sent by the consumers in the query history.<\/p>\n<p>Sometimes, either for logging purpose or to analyze and fix some bug, we need to identify the queries the database is receiving and executing.<\/p>\n<h2>Checking the Query History in Kusto Database<\/h2>\n<p>The statement is simple:<\/p>\n<pre class=\"lang:tsql decode:true \">.show query<\/pre>\n<p>\u00a0<\/p>\n<p>However, a simple execution may generate an error. The result is too huge, and it will exceed the capacity.<\/p>\n<p>A simple solution is to filter by the query history by execution time:<\/p>\n<pre class=\"lang:tsql decode:true \">.show queries\n| where StartedOn &gt; ago(2h)<\/pre>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"268\" class=\"wp-image-104501\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/11\/a-screenshot-of-a-computer-description-automatica-1.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<h2>The Field you are Looking for<\/h2>\n<p>Usually what we are looking for is the query text. Most of the times we want to locate the precise text generated by Power BI visuals or applications to confirm if the query is being generated correctly or how to optimize it.<\/p>\n<p>This result comes in the field called <strong>Text<\/strong>.<\/p>\n<p>The differences are what queries you would like to find and how do you plan to do it.<\/p>\n<ul>\n<li>You may be looking for a query which caused an error message<\/li>\n<li>You may be looking for the most recent queries, after you simulated some test<\/li>\n<li>You may be looking for the most expensive queries to optimize<\/li>\n<\/ul>\n<h2>Looking for the cause of an error in Query History<\/h2>\n<p>We can use the unique Ids in error messages to locate the precise query which caused the error message.<\/p>\n<p>This is the <strong>ClientActivityId<\/strong>, which in the error messages appear as <strong>ClientRequestId<\/strong>. Filtering by this value we will locate the specific query causing the error.<\/p>\n<pre class=\"lang:tsql decode:true \">.show queries\n| where ClientActivityId == \"KPBI;668bbe4d-1c57-4bd6-9e22-558f77c6eb3c;99a8b6e7-d544-421b-9299-6aa3b3c7abba;761ff106-9d7e-43fe-8d70-cfc8ea5a09cb\"<\/pre>\n<p>\u00a0<\/p>\n<p>This field can also be used as a filtering method to discover the queries we are looking for. The starting of the value tells us how the query was generated.<\/p>\n<p>I couldn&#8217;t find a full documentation, but this is what I discovered about the ClientActivityId in the query history:<\/p>\n<ul>\n<li>KPBI: A query generated in Power BI<\/li>\n<li>KD2RunQuery: I believe this one is from Data Activator<\/li>\n<li>Kusto.Web.RTA.Dashboards: Real-Time Dashboards<\/li>\n<li>kustoSynapseSpark: Queries executed from a notebook<\/li>\n<\/ul>\n<p>You can find queries related to these sources using the expresion <strong>startswith<\/strong> or <strong>!startswith<\/strong><\/p>\n<pre class=\"lang:tsql decode:true \">.show queries\n| where ClientActivityId startswith \"Kusto.Web.RTA.Dashboards\"<\/pre>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"256\" class=\"wp-image-104502\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/11\/a-screenshot-of-a-computer-description-automatica-2.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<h2>Looking for recent Queries<\/h2>\n<p>Sometimes we make a test, a simulation from some source, and we want to retrieve the query which arrived in the server.<\/p>\n<p>There are many fields we can use to filter and get the queries generated by our source. Check some interesting ones:<\/p>\n<p><strong>User:<\/strong> The username which sent the query. It&#8217;s the user used to authenticate in Kusto. This can vary a lot. Was the query executed interactively or through some resource?<\/p>\n<p>For example, if the query was executed from a report, then it is sent by the semantic model. If it was from Power BI desktop, it may send the authentication of the logged in user. However, from the portal, it will send the authentication specified in the Cloud Connection.<\/p>\n<p><strong>Application:<\/strong> The identification of the application sending the query. The identification may not be so obvious, but it may help.<\/p>\n<p>You can easily check the distinct values existing in these columns and identify which one corresponds to the source of your tests.<\/p>\n<pre class=\"lang:tsql decode:true \">.show queries\n| distinct Application<\/pre>\n<p>\u00a0<\/p>\n<h2>Looking for Failed Queries<\/h2>\n<p>Sometimes our purpose is to locate the queries causing errors or a specific error<\/p>\n<p>We can use the field <strong>State<\/strong> to filter queries according to the final result.<\/p>\n<p>These are possible values for the field <strong>State<\/strong>:<\/p>\n<ul>\n<li><strong>Completed:<\/strong> The query executed successfully<\/li>\n<li><strong>Failed:<\/strong> The query failed<\/li>\n<li><strong>Cancelled:<\/strong> The execution was cancelled in the middle<\/li>\n<\/ul>\n<p>We can filter the queries by the Failed state and use the field <strong>FailureReason<\/strong> to identify what was the error.<\/p>\n<p><strong>FailureReason<\/strong> contains a message which already tells us some details about the error, but it&#8217;s also a link. If we use CTRL+Click on the link, we will see a popup message about the error.<\/p>\n<h2>High Performance Consumption<\/h2>\n<p>A common need we may have about query history is to look for queries with high performance consumption.<\/p>\n<p>We can search the queries and order the result in descending orders by one of the fields below and this will give a list of the highest consumption queries being executed.<\/p>\n<ul>\n<li>Duration<\/li>\n<li>TotalCPU<\/li>\n<li>MemoryPeak<\/li>\n<\/ul>\n<p>The name of the fields already explains what they contain.<\/p>\n<p>We can use <strong>Order By<\/strong> or <strong>Top<\/strong>, the result is similar:<\/p>\n<pre class=\"lang:tsql decode:true \">.show queries\n| where StartedOn &gt; ago(3d)\n| top 10 by Duration desc<\/pre>\n<p>\u00a0<\/p>\n<h2>Deeper Query History Analysis<\/h2>\n<p>There are other fields such as CacheStatistics, ScannedExtentsStatistics and ResultSetStatistics which allow us to analyze the query in much deeper detail. I will write more about these in another newsletter.<\/p>\n<h2>Summary<\/h2>\n<p>Searching Kusto query history is an important step to debug problems and optimize queries<\/p>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>We can consume a Kusto database in Fabric from many different places: Notebooks, semantic models, real time dashboards and more. Kusto register all queries sent by the consumers in the query history. Sometimes, either for logging purpose or to analyze and fix some bug, we need to identify the queries the database is receiving and&#8230;&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":104503,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2,159164],"tags":[126249,158997,101611,159057],"coauthors":[6810],"class_list":["post-104500","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blogs","category-microsoft-fabric","tag-kusto","tag-microsoft-fabric","tag-power-bi","tag-real-time"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/104500","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=104500"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/104500\/revisions"}],"predecessor-version":[{"id":104504,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/104500\/revisions\/104504"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/104503"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=104500"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=104500"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=104500"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=104500"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}