<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>naga</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/naga/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/naga/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 04:09:28 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>SQL Server Performance Tuning : Table Variable Vs Temporary Tables</title>
      <link>https://docs.microsoft.com/archive/blogs/naga/sql-server-performance-tuning-table-variable-vs-temporary-tables</link>
      <pubDate>Sun, 10 May 2015 04:11:00 GMT</pubDate>
      <dc:creator><![CDATA[nagasuraj]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/naga/2015/05/10/sql-server-performance-tuning-table-variable-vs-temporary-tables/</guid>
      <description><![CDATA[We have quite often used temporary objects (Table Variables and Temporary Tables) for setting aside...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: arial,helvetica,sans-serif;">We have quite often used temporary objects (Table Variables and Temporary Tables) for setting aside intermediate results. Both have their advantages and disadvantages.&nbsp;So why use them at the first place? Well, in number of cases, complex queries involving many tables with sub-optimal query plans when broken down into smaller set of individual queries involving lesser joins helps in performance. The output from these smaller joins can be stored in a temporary objects and reused in other queries. This also helps specifically when repeated computations are involved.</span></p>
<p><span style="font-family: arial,helvetica,sans-serif;">Now what should be our choice - a Temporary Table or a Table Variable? </span></p>
<p><span style="font-family: arial,helvetica,sans-serif;">Let us walk through this with an example. Take a scenario where we want to fetch the count of transactions&nbsp; in a current year for different products on <strong>AdventureWorks2012</strong> Database. In addition, we would also like to show the no of transactions for last couple of years.</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;">Query1#Start#:</span></p>
<pre class="scroll"><code class="mysql">;With BASE AS<br /> (<br /> SELECT ProductID, YEAR(TransactionDate) AS TransCurrYear, COUNT(1) AS NoTrans<br /> FROM Production.TransactionHistory<br /> GROUP BY ProductID, YEAR(TransactionDate)<br /> )<br /> SELECT CurrYear.ProductID, CurrYear.NoTrans AS CurrTransCnt, PrevYear.NoTrans AS PrevTransCnt, Prev2Year.NoTrans AS Prev2YearCnt<br /> FROM BASE AS CurrYear<br /> CROSS APPLY (SELECT *<br /> FROM BASE PrevYear<br /> WHERE CurrYear.ProductID = PrevYear.ProductID<br /> AND CurrYear.TransCurrYear = PrevYear.TransCurrYear - 1 ) AS PrevYear<br /> OUTER APPLY (SELECT *<br /> FROM BASE Prev2Year<br /> WHERE CurrYear.ProductID = Prev2Year.ProductID<br /> AND CurrYear.TransCurrYear = Prev2Year.TransCurrYear - 2 ) AS Prev2Year</code></pre>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0741.B5Q2.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0741.B5Q2.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0741.B5Q2.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0741.B5Q2.jpg" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/6404.B5Q3.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/6404.B5Q3.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/6404.B5Q3.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/6404.B5Q3.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;">Query1#End#:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Observations from Query 1:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<ol style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal; margin-top: 0in; margin-bottom: 0in; margin-left: 0.375in; unicode-bidi: embed; direction: ltr;" type="a">
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;" value="1"><span style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal;">There were over 27 scans with&nbsp;logical reads of 1998</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt;">Although we used a CTE&nbsp;Operation, we could see that similar aggregations are being repeated in the plan.</span></li>
</ol>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Let's now use a Temporary Table.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;">Query2#Start#:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<pre class="scroll"><code class="mysql">CREATE TABLE #T1<br /> (ProductID int<br /> ,TransCurrYear int<br /> ,NoTrans int<br /> );<br /> <br /> CREATE CLUSTERED INDEX CI_#T1 ON #T1 (TransCurrYear)<br /> <br /> INSERT INTO #T1<br /> SELECT ProductID, YEAR(TransactionDate) AS TransCurrYear, COUNT(1) AS NoTrans<br /> FROM Production.TransactionHistory<br /> GROUP BY ProductID, YEAR(TransactionDate)<br /> ORDER BY YEAR(TransactionDate)<br /> <br /> ;With BASE AS<br /> (<br /> SELECT * FROM #T1<br /> )<br /> SELECT CurrYear.ProductID, CurrYear.NoTrans AS CurrTransCnt, PrevYear.NoTrans AS PrevTransCnt, Prev2Year.NoTrans AS Prev2YearCnt<br /> FROM BASE AS CurrYear<br /> CROSS APPLY (SELECT *<br /> FROM BASE PrevYear<br /> WHERE CurrYear.ProductID = PrevYear.ProductID<br /> AND CurrYear.TransCurrYear = PrevYear.TransCurrYear - 1 ) AS PrevYear<br /> OUTER APPLY (SELECT *<br /> FROM BASE Prev2Year<br /> WHERE CurrYear.ProductID = Prev2Year.ProductID<br /> AND CurrYear.TransCurrYear = Prev2Year.TransCurrYear - 2 ) AS Prev2Year</code></pre>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4010.B5Q5.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4010.B5Q5.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4010.B5Q5.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4010.B5Q5.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/7245.B5Q6.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/7245.B5Q6.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/7245.B5Q6.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/7245.B5Q6.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/3515.B5Q7.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/3515.B5Q7.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/3515.B5Q7.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/3515.B5Q7.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Query2#End#:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;">Observations from Query 2:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<ol style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal; margin-top: 0in; margin-bottom: 0in; margin-left: 0.375in; unicode-bidi: embed; direction: ltr;" type="a">
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;" value="1"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-style: normal; font-weight: normal;">Logical Reads are down when&nbsp;compared to Query1.</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: arial,helvetica,sans-serif; font-size: small;">No Repetition of&nbsp;computation of&nbsp;Aggregated Values.</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: arial,helvetica,sans-serif; font-size: small;">SQL Server uses statistics as&nbsp;can be seen from the properties above which is good when data is more.</span></li>
</ol>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small;">Great. Let's now do it with a </span><span style="font-family: arial,helvetica,sans-serif; font-size: small;">table variable</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;">Query3#Start#:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<pre class="scroll"><code class="mysql">DECLARE @T1 AS TABLE<br /> (ProductID int<br /> ,TransCurrYear int<br /> ,NoTrans int<br /> , INDEX [IX_TransactionYear] CLUSTERED (ProductID,TransCurrYear)<br /> );<br /> <br /> <br /> INSERT INTO @T1<br /> SELECT ProductID, YEAR(TransactionDate) AS TransCurrYear, COUNT(1) AS NoTrans<br /> FROM Production.TransactionHistory<br /> GROUP BY ProductID, YEAR(TransactionDate)<br /> ORDER BY YEAR(TransactionDate)<br /> <br /> ;With BASE AS<br /> (<br /> SELECT * FROM @T1<br /> )<br /> SELECT CurrYear.ProductID, CurrYear.NoTrans AS CurrTransCnt, PrevYear.NoTrans AS PrevTransCnt, Prev2Year.NoTrans AS Prev2YearCnt<br /> FROM BASE AS CurrYear<br /> CROSS APPLY (SELECT *<br /> FROM BASE PrevYear<br /> WHERE CurrYear.ProductID = PrevYear.ProductID<br /> AND CurrYear.TransCurrYear = PrevYear.TransCurrYear - 1 ) AS PrevYear<br /> OUTER APPLY (SELECT *<br /> FROM BASE Prev2Year<br /> WHERE CurrYear.ProductID = Prev2Year.ProductID<br /> AND CurrYear.TransCurrYear = Prev2Year.TransCurrYear - 2 ) AS Prev2Year</code></pre>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4846.B5Q9.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4846.B5Q9.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4846.B5Q9.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4846.B5Q9.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/5078.B5Q10.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/5078.B5Q10.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/5078.B5Q10.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/5078.B5Q10.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;">Query3#End#:</span>&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;">Observations from Query3:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<ol style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal; margin-top: 0in; margin-bottom: 0in; margin-left: 0.375in; unicode-bidi: embed; direction: ltr;" type="a">
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;" value="1"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-style: normal; font-weight: normal;">Scan Count and Logical Reads&nbsp;are slightly up.</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: arial,helvetica,sans-serif; font-size: small;">There is no statistics&nbsp;associated with Clustered Key Creation in Table Variable which can be seen&nbsp;from the <span style="font-weight: bold;">Estimated Number of Rows</span> Value. This could be bad when data is more. </span></li>
</ol>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small;">One reason why the </span><span style="font-family: arial,helvetica,sans-serif; font-size: small;">Optimizer could not sniff the "Estimated Number of Rows" is because </span><span style="font-family: arial,helvetica,sans-serif; font-size: small;">the entire batch query populates the variable table followed by querying on it. </span><span style="font-family: arial,helvetica,sans-serif; font-size: small;">And hence, it is not able to figure out the cardinality. If we add the <strong>RECOMPILE </strong></span><span style="font-family: arial,helvetica,sans-serif; font-size: small;">Option to the query, SQL Server is able to detect the cardinality like so,</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;">Query4#Start#:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<pre class="scroll"><code class="mysql">;With BASE AS<br /> (<br /> SELECT * FROM @T1<br /> )<br /> SELECT CurrYear.ProductID, CurrYear.NoTrans AS CurrTransCnt, PrevYear.NoTrans AS PrevTransCnt, Prev2Year.NoTrans AS Prev2YearCnt<br /> FROM BASE AS CurrYear<br /> CROSS APPLY (SELECT *<br /> FROM BASE PrevYear<br /> WHERE CurrYear.ProductID = PrevYear.ProductID<br /> AND CurrYear.TransCurrYear = PrevYear.TransCurrYear - 1 ) AS PrevYear<br /> OUTER APPLY (SELECT *<br /> FROM BASE Prev2Year<br /> WHERE CurrYear.ProductID = Prev2Year.ProductID<br /> AND CurrYear.TransCurrYear = Prev2Year.TransCurrYear - 2 ) AS Prev2Year<br /> OPTION (RECOMPILE)</code></pre>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0116.B5Q10_2.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0116.B5Q10_5F00_2.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0116.B5Q10_2.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0116.B5Q10_5F00_2.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p><strong>Query4#End#:</strong></p>
<p>One misconception we often hear is that Table Variables are&nbsp;always in memory and it does not incur any disk activity. That was never the case. With larger set of data, there can always be spill over to TempDB.</p>
<p>However, with SQL Server 2014, Table Variables can be defined as a Memory Optimized one by using the option of (MEMORY_OPTIMIZED = TRUE) .</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><strong><span style="font-family: arial,helvetica,sans-serif; font-size: small;">Query5#Start#:</span></strong></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<pre class="scroll"><code class="mysql">CREATE TYPE [ProductYearlyFigureType] AS TABLE(<br /> ProductID int NOT NULL<br /> ,TransCurrYear int NOT NULL<br /> ,NoTrans int<br /> , INDEX [IX_TransactionYear] NONCLUSTERED (ProductID,TransCurrYear) <br /> )<br /> WITH ( MEMORY_OPTIMIZED = ON ); <br /> <br /> <br /> DECLARE @T1 AS [ProductYearlyFigureType];<br /> <br /> <br /> INSERT INTO @T1<br /> SELECT ProductID, YEAR(TransactionDate) AS TransCurrYear, COUNT(1) AS NoTrans<br /> FROM Production.TransactionHistory<br /> GROUP BY ProductID, YEAR(TransactionDate)<br /> ORDER BY YEAR(TransactionDate)<br /> <br /> ;With BASE AS<br /> (<br /> SELECT * FROM @T1<br /> )<br /> SELECT CurrYear.ProductID, CurrYear.NoTrans AS CurrTransCnt, PrevYear.NoTrans AS PrevTransCnt, Prev2Year.NoTrans AS Prev2YearCnt<br /> FROM BASE AS CurrYear<br /> CROSS APPLY (SELECT *<br /> FROM BASE PrevYear<br /> WHERE CurrYear.ProductID = PrevYear.ProductID<br /> AND CurrYear.TransCurrYear = PrevYear.TransCurrYear - 1 ) AS PrevYear<br /> OUTER APPLY (SELECT *<br /> FROM BASE Prev2Year<br /> WHERE CurrYear.ProductID = Prev2Year.ProductID<br /> AND CurrYear.TransCurrYear = Prev2Year.TransCurrYear - 2 ) AS Prev2Year</code></pre>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0268.B5Q12.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0268.B5Q12.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0268.B5Q12.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0268.B5Q12.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-family: arial,helvetica,sans-serif; font-size: small; font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0211.B5Q13.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0211.B5Q13.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0211.B5Q13.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0211.B5Q13.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p><strong><span style="font-family: arial,helvetica,sans-serif; font-size: small;">Query5#End#:</span></strong></p>
<p><strong><span style="font-size: small;">Observations from Query5:</span></strong></p>
<ol>
<li value="1"><span style="font-size: small;">Scan Count and Logical Reads&nbsp;</span><span style="font-size: small;">are only to read from base table.</span></li>
<li><span style="font-size: small;">There is no Physical IO&nbsp;</span><span style="font-size: small;">involved when reading from memory optimized tables.&nbsp;&nbsp;</span>&nbsp;</li>
</ol>
<p><span style="font-size: small;">Apart from this, </span><span style="font-size: small;">there are few other differences between a Table Variable and a Temporary Table</span></p>
<ol>
<li value="1"><span style="font-size: small;">Scope of a Table Variable is&nbsp;</span><span style="font-size: small;">only within the batch that declared it whereas Temporary Tables are&nbsp;</span><span style="font-size: small;">visible&nbsp;within a&nbsp;session.</span></li>
<li><span style="font-size: small;">Creation of too many&nbsp;T</span><span style="font-size: small;">emporary Tables may result in contention of the SGAM Pages.</span></li>
<li><span style="font-size: small;">In events of rollback,&nbsp;</span><span style="font-size: small;">data&nbsp; processing in table variables&nbsp;</span><span style="font-size: small;">(within the transaction) are not rolled back or destroyed unlike the&nbsp;</span><span style="font-size: small;">temporary tables.</span></li>
</ol>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Hope this helps to de-mystify the difference between the two. Thanks</p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server Performance Tuning : Per-Row and Per-Index Plans</title>
      <link>https://docs.microsoft.com/archive/blogs/naga/sql-server-performance-tuning-per-row-and-per-index-plans</link>
      <pubDate>Sun, 03 May 2015 08:28:00 GMT</pubDate>
      <dc:creator><![CDATA[nagasuraj]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/naga/2015/05/03/sql-server-performance-tuning-per-row-and-per-index-plans/</guid>
      <description><![CDATA[One key operation done during a delete operation on a table is the updation of clustered and...]]></description>
      <content:encoded><![CDATA[<p>One key operation done during a delete operation on a table is the updation of clustered and non-clustered indexes. SQL Server performs this using the <strong>per-row</strong> or <strong>per-index</strong> maintenance plans. In a per-row scenario, SQL Server first updates the Clustered Index followed by the non-clustered indexes using a single operator.&nbsp;The per-Index maintenance plan however has different operators performing the update operations on clustered and non-clustered indexes.</p>
<p>The query optimizer is likely to choose a per-row plan when no of records to be deleted are low in number. If you closely look in a <strong>per-row</strong> plan, SQL Server uses the Clustered Index Key to fetch the keys to be updated on the non-clustered indexes.</p>
<p>During operations involving large deletes, we would usually see SQL Optimizer choosing a per-Index Plan. For non-clustered indexes, Table Spools are created including attributes which are part of the key and sorted based on the respective index.</p>
<p>For the purpose of this demonstration, I shall create a table and populate it like so,</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/6683.B5Q1.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/6683.B5Q1.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/6683.B5Q1.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/6683.B5Q1.jpg" alt="" border="0" /></a></p>
<p>I create few non-clustered indexes on the above&nbsp;table</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/5810.B5Q2.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/5810.B5Q2.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/5810.B5Q2.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/5810.B5Q2.jpg" alt="" border="0" /></a></p>
<p>Now, lets go execute the delete statements. In our scenario, <strong>Query1</strong> shall delete a single row whereas <strong>Query2</strong> will delete large number of rows.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4857.B5Q3.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4857.B5Q3.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4857.B5Q3.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4857.B5Q3.jpg" alt="" border="0" /></a></p>
<p>If we have the execution plan turned on, we shall observe similar to below. For <strong>Query1</strong>, we shall see that the same operator performs the updation operation on all indexes.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4456.B5Q4.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4456.B5Q4.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4456.B5Q4.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4456.B5Q4.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">For <strong>Query2</strong>, we can observe that SQL Server created separate spools for all non-clustered indexes which were again sorted based on how the index keys are arranged.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0675.B5Q5.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0675.B5Q5.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0675.B5Q5.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0675.B5Q5.jpg" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>There is an undocumented trace flag 8790 which may be invoked to force a per-index plan.You can validate that when no of records to be deleted are low, using this trace flag in fact deteriorates the performance.&nbsp;It is important to&nbsp;note that both maintenance plans may be used in the same query.</p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server Performance Tuning: Creating a Shell Database to tune your Production queries</title>
      <link>https://docs.microsoft.com/archive/blogs/naga/sql-server-performance-tuning-creating-a-shell-database-to-tune-your-production-queries</link>
      <pubDate>Sun, 26 Apr 2015 00:43:00 GMT</pubDate>
      <dc:creator><![CDATA[nagasuraj]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/naga/2015/04/26/sql-server-performance-tuning-creating-a-shell-database-to-tune-your-production-queries/</guid>
      <description><![CDATA[On so many occasions have we encountered situations wherein&nbsp;during&nbsp;a performance issue on...]]></description>
      <content:encoded><![CDATA[<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">On so many occasions have we encountered situations wherein&nbsp;during&nbsp;a performance issue on Production , we struggled to mimic or reproduce the issue on another environment. Some of the usual steps we&nbsp;follow, to debug these type of&nbsp;issues are :</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<ol style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal; margin-top: 0in; margin-bottom: 0in; margin-left: 0.375in; unicode-bidi: embed; direction: ltr;" type="a">
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;" value="1"><span style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal;">Request for a Read Access with permissions&nbsp;to access the DMVs on Production.</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt;">Request for a Production Backup&nbsp;and&nbsp;restore it on a&nbsp;different environment to analyze.</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt;">Run Extended Events / SQL Profiler&nbsp;on the Production Databases.</span></li>
</ol>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">These methods work and are quite fruitful too. But they can sometimes be time consuming (specially if we end up asking for a backup of the database)&nbsp;or could be less flexible to test out new things (if we want to create a&nbsp;new index) . Are there any&nbsp;quick ways? Sure is.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">One of the very interesting yet a less known feature SQL Server offers is that you can script out all the necessary metadata, statistics that a SQL Optimizer uses (to optimize a query) , and load it in another server to do the analysis.&nbsp;Some benefits&nbsp;are :</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<ol style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal; margin-top: 0in; margin-bottom: 0in; margin-left: 0.375in; unicode-bidi: embed; direction: ltr;" type="a">
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;" value="1"><span style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal;">The DBA is happy that&nbsp;you&nbsp;will not&nbsp;run excess load on production servers to tune the queries</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt;">There is no need to copy&nbsp;backup of huge databases across networks from production to test&nbsp;environments, thereby saving valuable time.</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt;">There is no need to figure&nbsp;out as big a disk space on your local environment as it is in Production.</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt;">In event of databases having&nbsp;sensitive information, there is no compromise as there is no movement or&nbsp;copying of data to another environment.</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt;">New indexes created on the&nbsp;shell database also have their statistics updated as per the stats&nbsp;available on other indexes in the table.</span></li>
</ol>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Just to note that this is absolutely not a panacea for creating an environment for doing all forms of performance tuning. It serves a purpose where we want to tune queries based on the statistics currently available on Production.&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Let's see how this can be done.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Step - 1 :</span> Right Click on the Database , go to Tasks -&gt; Generate Scripts</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/7103.B4S1.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/7103.B4S1.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/7103.B4S1.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/7103.B4S1.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><strong>Step - 2 :</strong> On the <em>Generate and Publish Script</em> Window, select the objects you want to script out.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><strong>Step - 3 :</strong> On the <em>Set Scripting Options</em> Tab of the Window, provide a location to where the file can be generated and then&nbsp; click on the <em>Advanced</em> Button&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/8244.B4S2.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/8244.B4S2.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/8244.B4S2.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/8244.B4S2.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><strong>Step - 4 :</strong> On the Advanced Scripting Objects, change the default values of the given properties to values mentioned below</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<div style="direction: ltr;">
<table style="border: 1pt solid #a3a3a3; border-collapse: collapse; direction: ltr;" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="padding: 4pt; border: 1pt solid #a3a3a3; width: 3.421in; vertical-align: top;">
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Property </span></p>
</td>
<td style="padding: 4pt; border: 1pt solid #a3a3a3; width: 2.81in; vertical-align: top;">
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Value</span></p>
</td>
</tr>
<tr>
<td style="padding: 4pt; border: 1pt solid #a3a3a3; width: 3.421in; vertical-align: top;">
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Script Statistics</p>
</td>
<td style="padding: 4pt; border: 1pt solid #a3a3a3; width: 2.81in; vertical-align: top;">
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Script Statistics&nbsp;and Histograms</p>
</td>
</tr>
<tr>
<td style="padding: 4pt; border: 1pt solid #a3a3a3; width: 3.421in; vertical-align: top;">
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Script Indexes</p>
</td>
<td style="padding: 4pt; border: 1pt solid #a3a3a3; width: 2.81in; vertical-align: top;">
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">True</p>
</td>
</tr>
</tbody>
</table>
</div>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Once Done, click on <em>Finish</em> to generate the script. This script may now be used to re-create the objects on a different environment.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Since I am performing the activities on the same machine, I have edited the script to change the database name from <span style="font-weight: bold;">AdventureWorks2012 </span>to <span style="font-weight: bold;">AdventureWorks2012Shell</span>.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Now, assuming a query&nbsp;(like the one below)&nbsp;is causing some performance challenge on production. &nbsp;This can now be run on this newly created database for analysis.&nbsp;One can observe that although there are no records returned, it uses the statistics from our source Database (Look at the <strong>Estimated Number of Rows</strong> Property), like so.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/5556.B4S4.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/5556.B4S4.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/5556.B4S4.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/5556.B4S4.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/6747.B5Q12.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/6747.B5Q12.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/6747.B5Q12.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/6747.B5Q12.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Now as part of the analysis, we would like to validate&nbsp;if creating a new index will help remove the clustered index scan. Let's go create one on column <strong>ModifiedDate</strong>.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/1067.B4S6.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/1067.B4S6.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/1067.B4S6.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/1067.B4S6.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Running the same query again, shows that the SQL Optimizer chose to use the newly created index. This way, we can&nbsp;validate usage of new indexes based on the statistics on our Production Server.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/3858.B5Q13.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/3858.B5Q13.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/3858.B5Q13.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/3858.B5Q13.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Thanks&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server Performance Tuning : Backward Scanning of an Index</title>
      <link>https://docs.microsoft.com/archive/blogs/naga/sql-server-performance-tuning-backward-scanning-of-an-index</link>
      <pubDate>Sun, 19 Apr 2015 02:17:00 GMT</pubDate>
      <dc:creator><![CDATA[nagasuraj]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/naga/2015/04/19/sql-server-performance-tuning-backward-scanning-of-an-index/</guid>
      <description><![CDATA[One of the key areas to investigate during performance optimization is the indexing strategy. Not...]]></description>
      <content:encoded><![CDATA[<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">One of the key areas to investigate during performance optimization is the indexing strategy. Not building the right index based on the read pattern may be disastrous specially when databases are big. In this article, I will cover a scenario around how SQL Server scans an index while reading <strong>BACKWARD</strong>, like when <strong>ORDER BY Col1 DESC</strong> is used in a query.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">We shall use the AdventureWorks2012 Database for demonstrating this.&nbsp;I will create&nbsp;a new table <strong>TransactionHistory2</strong> for this.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Query1:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/2248.B2Q1.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/2248.B2Q1.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/2248.B2Q1.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/2248.B2Q1.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">I will now add more rows to&nbsp;the table&nbsp;and follow it up by creating a Clustered and a non-Clustered Index on it</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Query2:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/5417.B2Q2.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/5417.B2Q2.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/5417.B2Q2.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/5417.B2Q2.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Query3: </span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0028.B2Q3.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0028.B2Q3.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0028.B2Q3.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0028.B2Q3.jpg" alt="" border="0" /></a></span></p>
<p>&nbsp;</p>
<p>As part of the demonstration, I will &nbsp;query for <em>TransactionID,TransactionDate,TransactionType</em> from&nbsp; table <strong>TransactionHistory2</strong> by filtering on the attribute <em>TransactionID</em>.</p>
<p>The machine I am using for the demonstration is&nbsp;a 64 bit OS with an Windows 8.1 Enterprise with 16 GB RAM. Also find below the CPU Configuration.</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/5428.B2Q4.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/5428.B2Q4.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/5428.B2Q4.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/5428.B2Q4.jpg" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">My&nbsp;first goal is&nbsp;to ensure that the queries that I picked up for my demonstration run with parallelism. The property <span style="font-weight: bold;">Cost threshold for Parallelism</span> on my SQL Instance is set to 5. I&nbsp;executed the below code changing the value of the predicate <em>TransactionID</em> such that the <strong>Estimated Subtree Cost</strong> for the query goes over 5. Note that the mentioned properties are of the <span style="font-weight: bold;">SELECT </span>operator.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Query4:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4657.B2Q5.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4657.B2Q5.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4657.B2Q5.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4657.B2Q5.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/2626.B2Q6.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/2626.B2Q6.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/2626.B2Q6.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/2626.B2Q6.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/1031.B2Q7.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/1031.B2Q7.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/1031.B2Q7.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/1031.B2Q7.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Now, with a value greater than 166000 (I have selected&nbsp; a much higher number)&nbsp;, I go fetch the data ordering first by the <em>TransactionDate</em> in <span style="text-decoration: underline;">Ascending Order</span> followed by <span style="text-decoration: underline;">Descending Order</span>.&nbsp;</p>
<p><strong>Query5:</strong>&nbsp;</p>
<p><strong><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/3404.B2Q8.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/3404.B2Q8.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/3404.B2Q8.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/3404.B2Q8.jpg" alt="" border="0" /></a></strong></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/7416.B2Q9.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/7416.B2Q9.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/7416.B2Q9.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/7416.B2Q9.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">And as expected, SQL Server scans the data in&nbsp;parallel. Lets do the same again but changing the direction of the ordering.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Query6:</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/8787.B2Q10.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/8787.B2Q10.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/8787.B2Q10.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/8787.B2Q10.jpg" alt="" border="0" /></a></span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0676.B2Q11.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0676.B2Q11.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0676.B2Q11.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0676.B2Q11.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/1682.B2Q12.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/1682.B2Q12.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/1682.B2Q12.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/1682.B2Q12.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><br />&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">SQL Server now&nbsp;choses a Clustered Scan but does not process the descending order clause with a parallel scan even while the <span style="font-weight: bold;">Estimated Subtree Cost</span> is over 17%. That&rsquo;s because, currently a <span style="font-weight: bold;">BACKWARD</span> scan is not possible with parallelism. It is good to be aware of&nbsp;such implications&nbsp;while designing&nbsp;indexes. If the requirement is to fetch data from tables in a descending order, it may be more performant to create an index in descending order. Similarly, if the data needed is&nbsp;ordered by multiple attributes, both in opposite direction of ordering&nbsp;, it will be prudent to store the data within the index in that&nbsp;fashion (column1, column2 desc ) else there will be an explicit sorting of data, which is quite avoidable in such cases.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Thanks for&nbsp;reading!!</p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server Performance Tuning: Data Access Method</title>
      <link>https://docs.microsoft.com/archive/blogs/naga/sql-server-performance-tuning-data-access-method</link>
      <pubDate>Sat, 18 Apr 2015 01:15:00 GMT</pubDate>
      <dc:creator><![CDATA[nagasuraj]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/naga/2015/04/18/sql-server-performance-tuning-data-access-method/</guid>
      <description><![CDATA[Writing Queries in SQL Server is not all that hard. But, writing Queries by understanding the...]]></description>
      <content:encoded><![CDATA[<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Writing Queries in SQL Server is not all that hard. But, writing Queries by understanding the different patterns SQL Server uses to fetch your data from the disk, resource&nbsp;utilization which&nbsp;can help build efficient query writing skills.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">There are multiple ways how SQL Server accesses data from the tables. To illustrate the point I make, I shall query a heap and a clustered tables in <span style="font-weight: bold;">AdventureWorksDW2012</span> in a few different ways</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">The clustered table taken for the example is <span style="font-weight: bold;">FactInternetSales </span>which has a Clustered Index on attributes <span style="font-weight: bold;">SalesOrderNumber </span>and <span style="font-weight: bold;">SalesOrderLineNumber.&nbsp; </span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">I shall create a heap table , like so</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/6683.P1.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/6683.P1.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/6683.P1.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/6683.P1.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">To draw a comparative analysis between the two tables, I have dropped all non-clustered indexes from table <span style="font-weight: bold;">FactInternetSales. </span>In addition,&nbsp;I have turned on the <em>Actual Execution Plan</em> and <em>STATISTICS IO , TIME</em> to understand the execution pattern for the below queries.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Query 1 :</span> Execute the Query on the Heap Table</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/2146.P2.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/2146.P2.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/2146.P2.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/2146.P2.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4505.P3.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4505.P3.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4505.P3.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4505.P3.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0676.P4.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0676.P4.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/0676.P4.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/0676.P4.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Query 2: </span>Execute the below query on the clustered Table without an Order By Clause</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4745.P5.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4745.P5.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4745.P5.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4745.P5.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/7587.P6.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/7587.P6.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/7587.P6.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/7587.P6.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/8802.P7.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/8802.P7.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/8802.P7.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/8802.P7.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="font-weight: bold;">Query 3: </span>Execute the below query on the clustered Table with an Order By Clause</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/7026.P8.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/7026.P8.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/7026.P8.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/7026.P8.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/3022.p9.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/3022.p9.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/3022.p9.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/3022.p9.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4885.P10.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4885.P10.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/4885.P10.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/4885.P10.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">Let's us list the differences between the above 3 queries -</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<ol style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal; margin-top: 0in; margin-bottom: 0in; margin-left: 0.375in; unicode-bidi: embed; direction: ltr;" type="a">
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;" value="1"><span style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: bold;">Query1</span><span style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal;"> as expected was a Table Scan&nbsp;with</span><span style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: bold;"> Ordered </span><span style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal;">Property Value&nbsp;as "False". Logical Reads measure 1313. CPU Time = 350 ms</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt; font-weight: bold;">Query2</span><span style="font-family: Calibri; font-size: 11pt;"> was a Clustered Index Scan&nbsp;with</span><span style="font-family: Calibri; font-size: 11pt; font-weight: bold;"> Ordered </span><span style="font-family: Calibri; font-size: 11pt;">Property Value&nbsp;as "False". Logical Reads measure 2062. CPU Time = 364 ms</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt; font-weight: bold;">Query3</span><span style="font-family: Calibri; font-size: 11pt;"> was a Clustered Index Scan&nbsp;with</span><span style="font-family: Calibri; font-size: 11pt; font-weight: bold;"> Ordered </span><span style="font-family: Calibri; font-size: 11pt;">Property Value&nbsp;as "True" and a new Property </span><span style="font-family: Calibri; font-size: 11pt; font-weight: bold;">Scan Direction</span><span style="font-family: Calibri; font-size: 11pt;"> as "FORWARD".&nbsp;Logical Reads measure 2061. CPU Time = 393 ms</span></li>
</ol>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">These above differences may be summarized into the following buckets, &nbsp;like so</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<ol style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal; margin-top: 0in; margin-bottom: 0in; margin-left: 0.375in; unicode-bidi: embed; direction: ltr;" type="a">
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;" value="1"><span style="font-family: Calibri; font-size: 11pt; font-style: normal; font-weight: normal;">Logical Reads Measure</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt;">CPU Time</span></li>
<li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11pt;">Ordered Property</span></li>
</ol>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="text-decoration: underline;">Logical Reads Measure</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">If we can use the <strong>DBCC IND</strong> command to get the number of data pages for both the tables , it will explain the difference in Logical measure between the&nbsp;Clustered Table and&nbsp;the Heap table. In this case, the clustered index is fragmented which means more IO as compared to that of the Heap Table. To understand more around the <span style="font-weight: bold;">DBCC IND </span>command, there is an excellent post by Paul Randal which&nbsp;can be referred&nbsp;from <a href="https://www.sqlskills.com/blogs/paul/inside-the-storage-engine-anatomy-of-a-page/">here</a>.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/3122.P11.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/3122.P11.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/59/3122.P11.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-59/3122.P11.jpg" alt="" border="0" /></a></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="text-decoration: underline;">&nbsp;CPU Time</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">In the event of a fragmented index (<strong>FactInternetSales </strong>Clustered Index is fragmented) , An Unordered Scan (<strong>Query2</strong>) may consume (not necessarily though!!)&nbsp;lesser resource (IO&nbsp;or/and CPU time)&nbsp;than an Ordered Scan (<strong>Query3</strong>).</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><span style="text-decoration: underline;">Ordered Property</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">&nbsp;</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;">In <strong>Query2</strong>, SQL Server did an Unordered Clustered Scan while&nbsp;<strong>Query3</strong> was an Ordered Scan.&nbsp;Both were full scans as expected. The first query however, had no requirement for an ordered set.&nbsp; SQL Server uses different algorithms to fetch the data -&nbsp;</p>
<ol>
<li>
<div style="margin: 0in; font-family: Calibri; font-size: 11pt;">For <strong>Query2</strong>, SQL Server reads the IAM Pages to fetch the list of pages which holds the data. Refer the <strong>sys.system_internal_allocation_units</strong> table to know more. This type of scan is called the allocation order scan (or a Unordered Clustered Scan) and&nbsp;it will not ensure the order of the dataset as per the clustered key.</div>
</li>
<li>
<div style="margin: 0in; font-family: Calibri; font-size: 11pt;">Where as in <strong>Query3</strong>,&nbsp;when we exclusively asked SQL Server to fetch the data in an ordered fashion, it&nbsp;scans through the binary tree&nbsp;of the Clustered Index.&nbsp;</div>
</li>
</ol>
<p style="margin: 0in; font-family: Calibri; font-size: 11pt;"><br />&nbsp;I do hope you find this useful. Thanks for reading. Do share your views/learnings on this.</p>]]></content:encoded>
    </item>
  </channel>
</rss>