<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'SQL Server 2008' and 'SQL Server 2012'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=SQL+Server+2008,SQL+Server+2012&amp;orTags=0</link><description>Search results matching tags 'SQL Server 2008' and 'SQL Server 2012'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>PowerPivot Compatibility across versions</title><link>http://sqlblog.com/blogs/marco_russo/archive/2013/01/14/powerpivot-compatibility-across-versions.aspx</link><pubDate>Mon, 14 Jan 2013 12:44:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:47140</guid><dc:creator>sqlbi</dc:creator><description>&lt;p&gt;There are several versions of PowerPivot available and starting with Excel 2013 there are also several versions of Excel. It is useful to look at the compatibility between the different versions of Excel and PowerPivot available now.&lt;/p&gt;  &lt;p&gt;As a general rule when you have a PowerPivot workbook saved with a specific version of PowerPivot:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You can upgrade a workbook to a newer version of PowerPivot &lt;/li&gt;    &lt;li&gt;You can upgrade a workbook to a newer version of Excel &lt;/li&gt;    &lt;li&gt;You cannot open a workbook using a previous version of PowerPivot &lt;/li&gt;    &lt;li&gt;You cannot open a workbook using a previous version of Excel, if it contains PowerPivot data &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;First caveat&lt;/strong&gt;: you can open an Excel 2010 workbook containing a PowerPivot data model in Excel 2013, but &lt;strong&gt;once you save it in Excel 2013, you can no longer open it in Excel 2010&lt;/strong&gt;. This is because a different file format for PowerPivot data used by Excel 2013 that cannot be understood by Excel 2010. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Second caveat&lt;/strong&gt;: A file saved in Excel 2010 with PowerPivot 2012 (RTM or SP1) cannot be opened by an Excel 2010 running PowerPivot 2008 R2.&lt;/p&gt;  &lt;p&gt;Each workbook has a compatibility level for PowerPivot data that corresponds to the PowerPivot version used to save the data. Here is the list of currently available compatibility levels:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;1050 (2008 R2) &lt;/li&gt;    &lt;li&gt;1100 (2012 RTM/SP1) &lt;/li&gt;    &lt;li&gt;1103 (Excel 2013) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The following table tells you what happens when you try to open an Excel 2010 file in a certain compatibility level (columns) with a certain version of PowerPivot (rows):&lt;/p&gt;  &lt;p&gt;   &lt;table cellspacing="0" cellpadding="0"&gt;       &lt;tr&gt;         &lt;td&gt;&amp;nbsp;&lt;/td&gt;          &lt;td&gt;           &lt;p&gt;1050&lt;/p&gt;         &lt;/td&gt;          &lt;td&gt;           &lt;p&gt;1100&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;           &lt;p&gt;2008 R2&lt;/p&gt;         &lt;/td&gt;          &lt;td&gt;           &lt;p&gt;Read/Modify&lt;/p&gt;         &lt;/td&gt;          &lt;td&gt;           &lt;p&gt;Not Supported&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;           &lt;p&gt;2012 RTM&lt;/p&gt;         &lt;/td&gt;          &lt;td&gt;           &lt;p&gt;Read/Upgrade++&lt;/p&gt;         &lt;/td&gt;          &lt;td&gt;           &lt;p&gt;Read/Modify&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;           &lt;p&gt;2012 SP1&lt;/p&gt;         &lt;/td&gt;          &lt;td&gt;           &lt;p&gt;Read/Upgrade++&lt;/p&gt;         &lt;/td&gt;          &lt;td&gt;           &lt;p&gt;Read/Modify/Upgrade&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/p&gt;  &lt;p&gt;++ It is important to call out that it is *&lt;b&gt;not&lt;/b&gt;* supported editing 1050 PowerPivot models in the 2012 release – you *&lt;b&gt;have to&lt;/b&gt;* upgrade the model to 110x before you can edit/refresh the model.&lt;/p&gt;  &lt;p&gt;A detailed list of errors you can have opening different a workbook with a different compatibility level than the current version of PowerPivot you have is available in the article &lt;a href="http://office.microsoft.com/en-us/excel-help/version-compatibility-between-powerpivot-data-models-in-excel-2010-and-excel-2013-HA103929426.aspx"&gt;Version compatibility between PowerPivot Data Models in Excel 2010 and Excel 2013&lt;/a&gt;. As the article mention, PowerPivot for SharePoint can open PowerPivot workbooks of previous compatibility levels, but in order to upgrade the data on the server (scheduling a data refresh) you need to upgrade the workbook to the newer format.&lt;/p&gt;  &lt;p&gt;You have to be careful using PowerPivot in mixed environment, especially when you want to share an Excel file containing PowerPivot data. Once you refresh PowerPivot data, you need to upgrade the compatibility level if you opened the workbook with a newer version of PowerPivot, and once you do that, your colleague with a previous version of PowerPivot can no longer open the same workbook. Saving the file on SharePoint makes it possible to navigate into data, but you need a correspondent or newer version of PowerPivot on SharePoint than that used to save the file.&lt;/p&gt;  &lt;p&gt;For these reasons, when we provide the examples for our &lt;a href="http://www.powerpivotworkshop.com"&gt;PowerPivot Workshop&lt;/a&gt; and our &lt;a href="http://www.sqlbi.com/books/powerpivot-for-excel-2010-give-your-data-meaning/"&gt;book for Excel 2010&lt;/a&gt;, the sample files are saved with the older version of PowerPivot (2008 R2). Now that we are working on the &lt;a href="http://www.sqlbi.com/books/excel-2013-building-data-models-with-powerpivot/"&gt;Excel 2013 version of the book&lt;/a&gt; and of the workshop (soon to be available!), we are finally going to release samples using a newer version of Excel and PowerPivot.&lt;/p&gt;</description></item><item><title>MS12-070 : Security Updates for all supported versions of SQL Server</title><link>http://sqlblog.com/blogs/aaron_bertrand/archive/2012/10/10/ms12-070-security-updates-for-all-supported-versions-of-sql-server.aspx</link><pubDate>Wed, 10 Oct 2012 16:57:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:45513</guid><dc:creator>AaronBertrand</dc:creator><description>&lt;p&gt;This week there was &lt;a target="_blank" href="http://technet.microsoft.com/en-us/security/bulletin/ms12-070"&gt;a security release for all supported versions of SQL Server&lt;/a&gt;. Each version has 32-bit and 64-bit patches, and each version has GDR (General Distribution Release) and QFE (Quick-Fix Engineering) patches. GDR should be applied if you are at the base (RTM or SP) build for your version, while QFE should be applied if you have installed any cumulative updates after the RTM or SP build. (&lt;a target="_blank" href="http://blogs.msdn.com/b/gauravagg/archive/2007/04/27/jargons-gdr-and-qfe-release.aspx"&gt;More details here&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;SQL Server 2005&lt;/b&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;RTM, SP1, SP2, SP3 - not supported&amp;nbsp;
&lt;/li&gt;&lt;li&gt;SP4 - GDR = 9.00.5069, QFE = 9.00.5324&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;SQL Server 2008&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RTM, SP1 - not supported&amp;nbsp;
&lt;/li&gt;&lt;li&gt;SP2 - GDR = 10.00.4067, QFE = 10.00.4371
&lt;/li&gt;&lt;li&gt;SP3 - GDR = 10.00.5512, QFE = 10.00.5826
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;SQL Server 2008 R2&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RTM - not supported&lt;/li&gt;
&lt;li&gt;SP1 - GDR = 10.50.2550, QFE = 10.50.2861&lt;/li&gt;
&lt;li&gt;SP2 - not affected&amp;nbsp;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;SQL Server 2012&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RTM: GDR = 11.00.2218, QFE = 11.00.2376&amp;nbsp;&lt;/li&gt;
&lt;li&gt;SP1 - not yet supported; should not be affected once SP1 is released.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;br&gt;Now, a couple of oddities you might have noticed:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The security bulletin mentions something about SQL Server instances with Reporting Services installed. Yet the KB articles for individual updates state that all instances of SQL Server are eligible for the update. And the update does, in fact, update sqlservr.exe and @@VERSION, even for systems where SSRS is not installed. So until there is some clarification on this point, I'm going to treat this as a patch for all instances.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Both the GDR and QFE KBs for multiple patches state that the preceding cumulative updates are included. I believe this is a copy &amp;amp; paste error and that the cumulative updates for a specific branch are only included with the QFE patch. I will update here if I get any confirmation on this.&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Even if they come back and say, whoops, our bad, the KBs should mention it is SSRS only, and the GDRs do not affect sqlservr.exe and do not include the CU updates, I'm still going to apply the patch everywhere. Why? Well, for consistency, I'd rather have all of my instances at @@VERSION = x, than have the SSRS instances at x and the non-SSRS instances at &amp;lt; x.&lt;br&gt;&amp;nbsp;&lt;/div&gt;</description></item><item><title>MDX Studio download #mdx #ssas</title><link>http://sqlblog.com/blogs/marco_russo/archive/2012/09/24/mdx-studio-download-mdx-ssas.aspx</link><pubDate>Mon, 24 Sep 2012 11:52:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:45305</guid><dc:creator>sqlbi</dc:creator><description>&lt;p&gt;Short version: the latest available version of MDX Studio can be downloaded from &lt;a href="http://www.sqlbi.com/tools/mdx-studio/"&gt;http://www.sqlbi.com/tools/mdx-studio/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Long version: Last week Stacia Misner twitted that the online version of MDX Studio was no longer available. It was hosted on &lt;a href="http://mdx.mosha.com/"&gt;&lt;font color="#0066cc"&gt;http://mdx.mosha.com&lt;/font&gt;&lt;/a&gt;. It was a sad news, and it is also not good that nobody is maintaining the desktop version of MDX Studio. The latest release is the 0.4.14 and as I am writing it is still available on a SkyDrive link provided by Mosha Pasumansky, who wrote MDX Studio. Mosha does not work in Microsoft now and the entire BI community hopes that somebody will continue its work on this product. Unfortunately, it cannot be published on CodePlex because of some IP restrictions.&lt;/p&gt;  &lt;p&gt;Only bad news? Well, I hope no. The first good news is that MDX Studio also works with Analysis Services 2012 in Multidimensional mode. The second news is that, after having checked that we can do that, we created a web page on SQLBI web site to download the latest available release of MDX Studio. I hope it will be necessary to update it in the future, by now it is just a way to simplify the finding and download of this precious tool, and to grant that it will not disappear in case the current SkyDrive using to host the download would be discontinued, like it happened to the MDX Studio online version.&lt;/p&gt;  &lt;p&gt;Now a question to the BI Community: I know that there was some content available regarding tutorial on MDX Studio. I’d like to gather it and to put all in a single place. If you have such content, please contact me directly writing to marco (dot) russo (at) sqlbi [dot] com. Thanks!&lt;/p&gt;</description></item><item><title>SSIS Design Patterns, the Book</title><link>http://sqlblog.com/blogs/andy_leonard/archive/2012/08/06/ssis-design-patterns-the-book.aspx</link><pubDate>Mon, 06 Aug 2012 16:37:43 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:44587</guid><dc:creator>andyleonard</dc:creator><description>&lt;p&gt;For the past two years, I have had the honor and privilege or authoring &lt;a href="http://www.amazon.com/SSIS-Design-Patterns-Matt-Masson/dp/1430237716" target="_blank"&gt;SSIS Design Patterns&lt;/a&gt; alongside Jessica Moss, Michelle Ufford, Tim Mitchell, and Matt Masson. Publication of the book – like many projects of this scope – has been delayed. The current publication date is 27 Aug 2012 and I have high confidence in this date. &lt;/p&gt;  &lt;p&gt;I take responsibility for publication delays and apologize to those who pre-ordered the book. The reasons for the delays are not important. I have built a career as a software developer and architect based on the following maxim:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Deliver quality late, no one remembers.       &lt;br /&gt;Deliver junk on time, no one forgets.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The shared goal of everyone working on this project has been to deliver quality. Proofing the manuscripts, I believe we have achieved that goal. &lt;/p&gt;  &lt;p&gt;:{&amp;gt;&lt;/p&gt;</description></item><item><title>The Curious Case of the Optimizer that doesn’t</title><link>http://sqlblog.com/blogs/hugo_kornelis/archive/2012/05/03/the-curious-case-of-the-optimizer-that-doesn-t.aspx</link><pubDate>Thu, 03 May 2012 22:13:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:43164</guid><dc:creator>Hugo Kornelis</dc:creator><description>&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;The
optimizer is the part of SQL Server that takes your query and reorders and
rearranges your query to find the optimal execution plan. In theory.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;In
practice, that doesn’t always work out well. Often, the optimizer manages to
come up with brilliant ways to execute a complex query very efficiently – but sometimes,
it misses an option that appears to be so simple that you can only stare in
utter amazement at the execution plan before going to the Connect site.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;Here is an
example I recently ran into. I tested it on SQL Server 2012 and on SQL Server
2008 R2, and it reproduces on both. Execute the query below in the
AdventureWorks sample database, with the option to Include Actual Execution Plan
enabled (Ctrl+M), or request an Estimated Execution Plan (Ctrl-L).&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="mso-layout-grid-align:none;text-autospace:none;"&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;color:blue;mso-ansi-language:EN-US;"&gt;SELECT&lt;/span&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;TerritoryID&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;br&gt;
&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;Name&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;br&gt;
&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;SalesLastYear&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;br&gt;
&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;SalesYTD&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;br&gt;
&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:fuchsia;"&gt;RANK&lt;/span&gt;&lt;span style="color:gray;"&gt;()&lt;/span&gt; &lt;span style="color:blue;"&gt;OVER &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:blue;"&gt;BY&lt;/span&gt; &lt;span style="color:teal;"&gt;SalesLastYear&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; &lt;span style="color:teal;"&gt;Rank1&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;br&gt;
&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:fuchsia;"&gt;RANK&lt;/span&gt;&lt;span style="color:gray;"&gt;()&lt;/span&gt; &lt;span style="color:blue;"&gt;OVER &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:blue;"&gt;BY&lt;/span&gt; &lt;span style="color:teal;"&gt;SalesYTD&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; &lt;span style="color:teal;"&gt;Rank2&lt;/span&gt;&lt;br&gt;
&lt;span style="color:blue;"&gt;FROM&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;Sales&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:teal;"&gt;SalesTerritory&lt;/span&gt;&lt;br&gt;
&lt;span style="color:blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:blue;"&gt;BY&lt;/span&gt; &lt;span style="color:teal;"&gt;SalesLastYear&lt;/span&gt;&lt;span style="color:gray;"&gt;;&lt;/span&gt;&lt;br style="mso-special-character:line-break;"&gt;
&lt;br style="mso-special-character:line-break;"&gt;
&lt;/span&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;When
following the flow of data (by reading the execution plan from right to left),
we see that the data is first read (with an unordered clustered index scan,
since there is no better index available), then sorted by SalesLastYear, so
that Rank1 can be computed (using two Segment operators and a Sequence Project operator
– don’t ask). After that, the rows are sorted again, now by SalesYTD, and we
see another combination of two Segment and one Sequence Project, for the
calculation of Rank2. And then, finally, the rows are re-sorted by SalesLastYear
so that they can be returned in the requested order.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;Now the big
question is: why does the plan include two sort operators that both sort the
data in the same (SalesLastYear) order? If the task of the optimizer is to find
smart ways to rearrange computation order for better performance, why doesn’t
it simply compute Rank2 first and Rank1 after that? In that case, the rows are
already in the SalesLastYear order after the last Sequence Project, so no extra
sort is needed. The execution plan of the query below confirms this suspicion:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="mso-layout-grid-align:none;text-autospace:none;"&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;color:blue;mso-ansi-language:EN-US;"&gt;SELECT&lt;/span&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;TerritoryID&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;Name&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;SalesLastYear&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;SalesYTD&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:fuchsia;"&gt;RANK&lt;/span&gt;&lt;span style="color:gray;"&gt;()&lt;/span&gt; &lt;span style="color:blue;"&gt;OVER &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:blue;"&gt;BY&lt;/span&gt; &lt;span style="color:teal;"&gt;SalesYTD&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; &lt;span style="color:teal;"&gt;Rank2,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:fuchsia;"&gt;RANK&lt;/span&gt;&lt;span style="color:gray;"&gt;()&lt;/span&gt; &lt;span style="color:blue;"&gt;OVER &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:blue;"&gt;BY&lt;/span&gt; &lt;span style="color:teal;"&gt;SalesLastYear&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; &lt;span style="color:teal;"&gt;Rank1&lt;/span&gt;&lt;br&gt;
&lt;span style="color:blue;"&gt;FROM&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;Sales&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:teal;"&gt;SalesTerritory&lt;/span&gt;&lt;br&gt;
&lt;span style="color:blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:blue;"&gt;BY&lt;/span&gt; &lt;span style="color:teal;"&gt;SalesLastYear&lt;/span&gt;&lt;span style="color:gray;"&gt;;&lt;/span&gt;&lt;br style="mso-special-character:line-break;"&gt;
&lt;br style="mso-special-character:line-break;"&gt;
&lt;/span&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;Indeed, the
execution plan of this query includes only two Sort operators instead of the
three we had in the first execution plan. If you include both queries in a single
batch, you’ll see an estimated cost of 59% for the first query, and 41% for the
second. (Some people think that the percentages shown in an Actual Execution
Plan are an indication of the actual cost; that is not the case – the percentages
are computed from the &lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;i style="mso-bidi-font-style:normal;"&gt;Estimated&lt;/i&gt;&lt;/b&gt; Subtree Cost property of
the left-most SELECT operator). The SalesTerritory table is too small to
measure any actual performance differences, but I tried queries with a similar
pattern on the SalesOrderDetail table (121,317 rows), and on
FactProductInventory in AdventureWorksDW (776,286 rows) and I did see an actual
difference in execution time. No surprise, but now I know for sure!&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;So, we have
seen that simply reordering the two columns that use an OVER clause reduces the
query cost by about 30%. How is it possible that such a simple, basic
reordering strategy is not considered by the optimizer? Surely, this can only be
a bug?&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;That’s what
Fabiano Neves Amorim thought when he filed &lt;a href="https://connect.microsoft.com/SQLServer/feedback/details/679342"&gt;this bug
on Connect&lt;/a&gt;. But, as you can see, the bug has been closed as “By design”. That
probably doesn’t mean that someone wrote a design document telling the
optimizer team to make sure that OVER clauses must always be evaluated in the
order in which they appear in the query, even if a different order would be
cheaper. I rather think of it as “missing an optimization opportunity is not a
bug; the results are still correct, just a bit slower – so we’re going to close
this “bug” report”. In this case, maybe the optimization opportunity was not
identified during the design phase, or it was just too hard to implement. The
latter statement may sound ridiculous at first (how can such a basic rewrite be
too hard?), but you have to be aware that the optimizer does not operate on the
original query text, but on an internal representation that is based on
mathematics and set theory. Rewrites that may be complex in the query text may
be obvious in this representation, but the reverse can also be true – so I’m
prepared to accept the comment that Andrew Richardson made on behalf of
Microsoft to the above Connect item: that it would be fairly complicated for
the Query Optimizer.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;That does
not mean I agree with the rest of Andrew’s comment. He suggests that this is a
case where we should not rely on the optimizer, but rewrite our queries
ourselves, especially since it’s such an easy rewrite in this case. Well, I
would agree with that, except that: (a) this missed optimization opportunity is
not documented, so how are developers supposed to know that they may need to
reorder columns in a SELECT clause for optimal performance? (that is one of the
reasons for this blog post); and (b) the behavior of the optimizer in this
situation is not documented, so it can change at any time; I’d hate to rewrite
all my queries and then find that the sysadmin just installed a patch and now
the optimizer always starts with the &lt;b style="mso-bidi-font-weight:normal;"&gt;last&lt;/b&gt;
instead of the first OVER clause (or, worse, I don’t find it and just get all
the bad performance right back).&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;However,
Andrew is right in so far that, at this time, rewriting queries does
consistently improve performance in all my tests. So at this time, rewriting
does seem to be the right thing to do. Just keep in mind that you have to test
all your queries, not only on your test server but also on your production
hardware, and that you’ll have to repeat these tests on a regular basis (at
least after each patch, CU, service pack, or other change).&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;The basic
rewrite pattern is simple – for each query that uses OVER clauses with
different ORDER BY subclauses as well as an ORDER BY clause on the query that
matches one of the ORDER BY subclauses, make sure that the OVER clause that
uses the matching ORDER BY comes last in the SELECT list. If you have a client
that expects the columns in a particular order, the rewrite becomes a bit more
complex – in that case, you have to use a CTE that includes the OVER clauses in
the optimized order, and then you can reorder the columns in the query that
references the CTE – as shown in this example:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="mso-layout-grid-align:none;text-autospace:none;"&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;color:blue;mso-ansi-language:EN-US;"&gt;WITH&lt;/span&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt; &lt;span style="color:teal;"&gt;MyCTE&lt;/span&gt;&lt;br&gt;
&lt;span style="color:blue;"&gt;AS &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;TerritoryID&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;Name&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;SalesLastYear&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;SalesYTD&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:fuchsia;"&gt;RANK&lt;/span&gt;&lt;span style="color:gray;"&gt;()&lt;/span&gt; &lt;span style="color:blue;"&gt;OVER &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:blue;"&gt;BY&lt;/span&gt; &lt;span style="color:teal;"&gt;SalesYTD&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; &lt;span style="color:teal;"&gt;Rank2&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:fuchsia;"&gt;RANK&lt;/span&gt;&lt;span style="color:gray;"&gt;()&lt;/span&gt; &lt;span style="color:blue;"&gt;OVER &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:blue;"&gt;BY&lt;/span&gt; &lt;span style="color:teal;"&gt;SalesLastYear&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; &lt;span style="color:teal;"&gt;Rank1&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;FROM&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;Sales&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:teal;"&gt;SalesTerritory&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style="color:blue;"&gt;SELECT&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;TerritoryID&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;Name&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;SalesLastYear&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;SalesYTD&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;Rank1&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;br&gt;
&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;Rank2&lt;/span&gt;&lt;br&gt;
&lt;span style="color:blue;"&gt;FROM&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:teal;"&gt;MyCTE&lt;/span&gt;&lt;br&gt;
&lt;span style="color:blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:blue;"&gt;BY&lt;/span&gt; &lt;span style="color:teal;"&gt;SalesLastYear&lt;/span&gt;&lt;span style="color:gray;"&gt;;&lt;br style="mso-special-character:line-break;"&gt;
&lt;br style="mso-special-character:line-break;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;These
rewrites are indeed the best option for the time being – but I still think that
the optimizer should be improved to do these rewrites internally. So I decided
to file &lt;a href="https://connect.microsoft.com/SQLServer/feedback/details/740437/avoid-extra-sort-in-queries-with-multiple-over-clauses"&gt;a
new item on Connect&lt;/a&gt;, this time labeling it as a suggestion instead of a
bug. If you agree with me that this would be a great investment of Microsoft’s
engineering time, then please add your vote to this item. (Or vote it down if
you think I’m just being ridiculous). But don’t stop there! Microsoft knows me;
they know I’m a geek who plays around with options like this and then runs into
this issue. No real production databases were hurt during the production of
this blog. And if I am the only one, then, frankly, I myself will say that they
have better things to do with their engineering time. However, if I know that this
affects real people, I can make a much stronger case to Microsoft for getting
this fixed.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;So – go out
to your production servers and find if you use queries with this pattern (two OVER
clauses with different ORDER BY and an ORDER BY on the final query), then check
to see if you should rewrite them. And then report back – add a comment here or
on the Connect item; share if this affected you, and how much performance you
were able to gain as a result of the rewrite.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:EN-US;"&gt;If
Microsoft knows that their customers would actually benefit, they’ll be much
more inclined to add this improvement to the optimizer then if it’s just about
me, a geek moaning about an edge case that no one in the real world would ever
run into.&lt;/span&gt;&lt;/p&gt;</description></item><item><title>Busy months ahead</title><link>http://sqlblog.com/blogs/hugo_kornelis/archive/2012/02/16/busy-months-ahead.aspx</link><pubDate>Thu, 16 Feb 2012 19:48:01 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:41778</guid><dc:creator>Hugo Kornelis</dc:creator><description>&lt;p&gt;Almost two months have passed since my last blog post. And while it’s true that I’ve had (much) longer breaks, I do have a good reason now. All the time that I would normally at least in part spend on preparing new blog posts is now reserved for preparing presentations for a few upcoming events. I’ll give you an overview – who knows, maybe you’ll have a chance to attend one of them and meet me there? I’m looking forward to it!&lt;/p&gt;  &lt;p&gt;On Saturday, February 25, I’ll present my session on “Advanced Indexing” at &lt;a href="http://sqlsaturday.com/108/eventhome.aspx"&gt;SQL Saturday 108, in Redmond, WA&lt;/a&gt;. This session covers included columns, filtered indexes, indexed views, tools for finding the right indexes, and the dangers of over-indexing. I see several top speakers on the agenda, so this is definitely an event you don’t want to miss out – especially considering the price! Unfortunately, I hear that the event is fully booked, but you can still get yourself added to the waiting list. If other people have to cancel, you may get a chance to get admitted.&lt;/p&gt;  &lt;p&gt;I’ll stay in the Redmond area the whole next week, attending the MVP Summit. Not as a presenter, but to soak up all the information the product team wishes to share with us, and to give feedback on current and planned functionality. And to have lots of funs with my fellow MVPs, of course!&lt;/p&gt;  &lt;p&gt;Shortly after that, I’ll be heading to &lt;a href="http://sqlsaturday.com/115/eventhome.aspx"&gt;SQL Saturday 115, in Lisbon, Portugal&lt;/a&gt;. I will first present a full-day training session on database design on Friday, March 16. The design method I’ll teach is one that observes all the principles of modelling I presented in some &lt;a href="http://sqlblog.com/blogs/hugo_kornelis/archive/2011/10/20/principles-of-modeling-the-jargon-principle.aspx"&gt;previous&lt;/a&gt; &lt;a href="http://sqlblog.com/blogs/hugo_kornelis/archive/2011/10/29/principles-of-modeling-the-concreteness-principle.aspx"&gt;blog&lt;/a&gt; &lt;a href="http://sqlblog.com/blogs/hugo_kornelis/archive/2011/12/22/principles-of-modeling-the-reproducibility-principle.aspx"&gt;posts&lt;/a&gt;. The next day, I’ll present two sessions: the one on advanced indexing I already mention above; and one about the MERGE statement, that covers not only the intended use but also several other interesting possibilities of this statement – and warns about some caveats that you need to know if you want to use MERGE. This event has an awesome line-up of speakers, so if you see a chance to go to Lisbon, do so!&lt;/p&gt;  &lt;p&gt;And finally, I’ll head to London for &lt;a href="http://sqlbits.com/"&gt;SQLBits X&lt;/a&gt;, which lasts from Thursday, March 29 until Saturday, March 31. On Thursday, I’ll present a training day on database design, so if you can’t attend in Lisbon, you get a second chance in London. I then have a day off on Friday, which gives me a chance to attend some of the superb sessions that are scheduled for this day; on Saturday, I will present a session on columnar indexes, a new feature introduced in SQL Server 2012 that has the potential to yield enormous performance benefits for queries that have to process large tables of read-only (or mainly read-only) data. In this session, I will peek below the hood and disclose a bit about &lt;i&gt;how&lt;/i&gt; this new kind of indexes works, and why that results in such enormous performance benefits.&lt;/p&gt;  &lt;p&gt;So, if you were waiting for my next blog post with actual technical content, I have to disappoint you. That will probably have to wait until after these busy conference weeks are over.&lt;/p&gt;</description></item><item><title>Session memory – who’s this guy named Max and what’s he doing with my memory?</title><link>http://sqlblog.com/blogs/extended_events/archive/2010/12/08/session-memory-who-s-this-guy-named-max-and-what-s-he-doing-with-my-memory.aspx</link><pubDate>Wed, 08 Dec 2010 06:12:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:31434</guid><dc:creator>extended_events</dc:creator><description>&lt;p&gt;SQL Server MVP Jonathan Kehayias (&lt;a href="http://sqlblog.com/blogs/jonathan_kehayias/default.aspx" target="_blank"&gt;blog&lt;/a&gt;) emailed me a question last week when he noticed that the total memory used by the buffers for an event session was larger than the value he specified for the MAX_MEMORY option in the CREATE EVENT SESSION DDL. The answer here seems like an excellent subject for me to kick-off my new &amp;ldquo;401 &amp;ndash; Internals&amp;rdquo; tag that identifies posts where I pull back the curtains a bit and let you peek into what&amp;rsquo;s going on inside the extended events engine.&lt;/p&gt;
&lt;p&gt;In a previous post (&lt;a href="http://sqlblog.com/b/extended_events/archive/2010/03/31/option-trading-getting-the-most-out-of-the-event-session-options.aspx" target="_blank"&gt;Option Trading: Getting the most out of the event session options&lt;/a&gt;) I explained that we use a set of buffers to store the event data before&amp;nbsp; we write the event data to asynchronous targets. The MAX_MEMORY along with the MEMORY_PARTITION_MODE defines how big each buffer will be. Theoretically, that means that I can predict the size of each buffer using the following formula:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;max memory / # of buffers = buffer size&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If it was that simple I wouldn&amp;rsquo;t be writing this post.&lt;/p&gt;
&lt;h3&gt;I&amp;rsquo;ll take &amp;ldquo;boundary&amp;rdquo; for 64K Alex&lt;/h3&gt;
&lt;p&gt;For a number of reasons that are beyond the scope of this blog, we create event buffers in 64K chunks. The result of this is that the buffer size indicated by the formula above is rounded up to the next 64K boundary and that is the size used to create the buffers. If you think visually, this means that the graph of your max_memory option compared to the actual buffer size that results will look like a set of stairs rather than a smooth line. You can see this behavior by looking at the output of dm_xe_sessions, specifically the fields related to the buffer sizes, over a range of different memory inputs:&lt;/p&gt;
&lt;p&gt;Note: This test was run on a 2 core machine using per_cpu partitioning which results in 5 buffers. (Seem my previous post referenced above for the math behind buffer count.)&lt;/p&gt;
&lt;table style="width:468px;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;input_memory_kb&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;total_regular_buffers&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;regular_buffer_size&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;total_buffer_size&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;637&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;130867&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;654335&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;638&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;130867&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;654335&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#008000;"&gt;639&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#008000;"&gt;5&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#008000;"&gt;130867&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#008000;"&gt;654335&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#800080;"&gt;640&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#800080;"&gt;5&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#800080;"&gt;196403&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#800080;"&gt;982015&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;641&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;196403&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;982015&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;642&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;196403&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;982015&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;p&gt;This is just a segment of the results that shows one of the &amp;ldquo;jumps&amp;rdquo; between the buffer boundary at 639 KB and 640 KB. You can verify the size boundary by doing the math on the regular_buffer_size field, which is returned in bytes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;196403 &amp;ndash; 130867 = 65536 bytes&lt;/p&gt;
&lt;p&gt;65536 / 1024 = 64 KB&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The relationship between the input for max_memory and when the regular_buffer_size is going to jump from one 64K boundary to the next is going to change based on the number of buffers being created. The number of buffers is dependent on the partition mode you choose. If you choose any partition mode other than NONE, the number of buffers will depend on your hardware configuration. (Again, see the earlier post referenced above.) With the default partition mode of none, you always get three buffers, regardless of machine configuration, so I generated a &amp;ldquo;range table&amp;rdquo; for max_memory settings between 1 KB and 4096 KB as an example.&lt;/p&gt;
&lt;table style="width:597px;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;start_memory_range_kb&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;end_memory_range_kb&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;total_regular_buffers&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;regular_buffer_size&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;total_buffer_size&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;191&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;NULL&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;NULL&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;NULL&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;192&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;383&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;130867&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;392601&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;384&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;575&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;196403&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;589209&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#008000;"&gt;576&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#008000;"&gt;767&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#008000;"&gt;3&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#008000;"&gt;261939&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="color:#008000;"&gt;785817&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;768&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;959&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;327475&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;982425&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;960&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1151&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;393011&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1179033&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1152&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1343&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;458547&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1375641&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1344&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1535&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;524083&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1572249&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1536&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1727&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;589619&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1768857&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1728&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1919&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;655155&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1965465&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1920&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2111&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;720691&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2162073&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;2112&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2303&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;786227&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2358681&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;2304&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2495&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;851763&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2555289&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;2496&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2687&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;917299&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2751897&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;2688&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2879&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;982835&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2948505&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;2880&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3071&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1048371&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3145113&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;3072&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3263&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1113907&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3341721&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;3264&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3455&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1179443&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3538329&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;3456&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3647&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1244979&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3734937&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;3648&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3839&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1310515&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3931545&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;3840&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;4031&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1376051&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;4128153&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;4032&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;4096&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1441587&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;4324761&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;p&gt;As you can see, there are 21 &amp;ldquo;steps&amp;rdquo; within this range and max_memory values below 192 KB fall below the 64K per buffer limit so they generate an error when you attempt to specify them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Clarification: &lt;/strong&gt;I got another question about this topic last week, this time from a student in one of Jonathan Kehayias' classes. Someone noticed that if you take the size of the buffer (regular_buffer_size) and divide that by 64 KB you don't get the nice even boundary that I am claiming above and that someone is wondering "What gives?". A reasonable question.&lt;/p&gt;
&lt;p&gt;What gives is that regular_buffer_size is reporting the usable buffer space, or the space left after we subtract a small amount of memory for the overhead of managing the buffers. You'll notice that if you take any regular_buffer_size and divide it by 64 KB you'll have the same fraction left over every time: 0.99687194824219, that's the overhead.&lt;/p&gt;
&lt;h3&gt;Max approximates True as memory approaches 64K&lt;/h3&gt;
&lt;p&gt;The upshot of this is that the max_memory option does not imply a contract for the maximum memory that will be used for the session buffers (Those of you who read &lt;a href="http://sqlblog.com/b/extended_events/archive/2010/06/28/take-it-to-the-max-and-beyond.aspx" target="_blank"&gt;Take it to the Max (and beyond)&lt;/a&gt; know that max_memory is really only referring to the event session buffer memory.) but is more of an estimate of total buffer size to the nearest higher multiple of 64K times the number of buffers you have. The maximum delta between your initial max_memory setting and the true total buffer size occurs right after you break through a 64K boundary, for example if you set max_memory = 576 KB (see the green line in the table), your actual buffer size will be closer to 767 KB in a non-partitioned event session. You get &amp;ldquo;stepped up&amp;rdquo; for every 191 KB block of initial max_memory which isn&amp;rsquo;t likely to cause a problem for most machines.&lt;/p&gt;
&lt;p&gt;Things get more interesting when you consider a partitioned event session on a computer that has a large number of logical CPUs or NUMA nodes. Since each buffer gets &amp;ldquo;stepped up&amp;rdquo; when you break a boundary, the delta can get much larger because it&amp;rsquo;s multiplied by the number of buffers. For example, a machine with 64 logical CPUs will have 160 buffers using per_cpu partitioning or if you have 8 NUMA nodes configured on that machine you would have 24 buffers when using per_node. If you&amp;rsquo;ve just broken through a 64K boundary and get &amp;ldquo;stepped up&amp;rdquo; to the next buffer size you&amp;rsquo;ll end up with total buffer size approximately 10240 KB and 1536 KB respectively (64K * # of buffers) larger than max_memory value you might think you&amp;rsquo;re getting. Using per_cpu partitioning on large machine has the most impact because of the large number of buffers created. If the amount of memory being used by your system within these ranges is important to you then this is something worth paying attention to and considering when you configure your event sessions.&lt;/p&gt;
&lt;p&gt;The DMV dm_xe_sessions is the tool to use to identify the exact buffer size for your sessions. In addition to the regular buffers (read: event session buffers) you&amp;rsquo;ll also see the details for large buffers if you have configured MAX_EVENT_SIZE. The &amp;ldquo;buffer steps&amp;rdquo; for any given hardware configuration should be static within each partition mode so if you want to have a handy reference available when you configure your event sessions you can use the following code to generate a range table similar to the one above that is applicable for your specific machine and chosen partition mode.&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0c0c0;"&gt;DECLARE @buf_size_output table (input_memory_kb bigint, total_regular_buffers bigint, regular_buffer_size bigint, total_buffer_size bigint) &lt;br /&gt;DECLARE @buf_size int, @part_mode varchar(8) &lt;br /&gt;SET @buf_size = 1 -- Set to the begining of your max_memory range (KB) &lt;br /&gt;SET @part_mode = 'per_cpu' -- Set to the partition mode for the table you want to generate &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0c0c0;"&gt;WHILE @buf_size &amp;lt;= 4096 -- Set to the end of your max_memory range (KB) &lt;br /&gt;BEGIN &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BEGIN TRY &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0c0c0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF EXISTS (SELECT * from sys.server_event_sessions WHERE name = 'buffer_size_test') &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DROP EVENT SESSION buffer_size_test ON SERVER &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DECLARE @session nvarchar(max) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET @session = 'create event session buffer_size_test on server &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; add event sql_statement_completed &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; add target ring_buffer &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; with (max_memory = ' + CAST(@buf_size as nvarchar(4)) + ' KB, memory_partition_mode = ' + @part_mode + ')' &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0c0c0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXEC sp_executesql @session &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0c0c0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET @session = 'alter event session buffer_size_test on server &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; state = start' &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0c0c0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXEC sp_executesql @session &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0c0c0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INSERT @buf_size_output (input_memory_kb, total_regular_buffers, regular_buffer_size, total_buffer_size) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT @buf_size, total_regular_buffers, regular_buffer_size, total_buffer_size FROM sys.dm_xe_sessions WHERE name = 'buffer_size_test' &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; END TRY &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BEGIN CATCH &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INSERT @buf_size_output (input_memory_kb) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT @buf_size &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; END CATCH &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET @buf_size = @buf_size + 1 &lt;br /&gt;END &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0c0c0;"&gt;DROP EVENT SESSION buffer_size_test ON SERVER &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0c0c0;"&gt;SELECT MIN(input_memory_kb) start_memory_range_kb, MAX(input_memory_kb) end_memory_range_kb, total_regular_buffers, regular_buffer_size, total_buffer_size from @buf_size_output group by total_regular_buffers, regular_buffer_size, total_buffer_size&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Thanks to Jonathan for an interesting question and a chance to explore some of the details of Extended Event internals.&lt;/p&gt;
&lt;p&gt;- Mike&lt;/p&gt;</description></item></channel></rss>