<?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>Linchi Shea : SQL Server 2005</title><link>http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx</link><description>Tags: SQL Server 2005</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Pause the passive node to apply SQL2005 Service Pack or hotfix</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2009/10/04/pause-the-passive-node-to-apply-sql2005-service-pack-or-hotfix.aspx</link><pubDate>Mon, 05 Oct 2009 01:55:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:17262</guid><dc:creator>Linchi Shea</dc:creator><slash:comments>7</slash:comments><comments>http://sqlblog.com/blogs/linchi_shea/comments/17262.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/linchi_shea/commentrss.aspx?PostID=17262</wfw:commentRss><description>With SQL Server 2005, Microsoft tried to be helpful in enabling its installer to apply the service pack or hotfix automatically on the passive node(s) in a cluster. In my own experience, this has not worked out too well. Very often, when the installer...(&lt;a href="http://sqlblog.com/blogs/linchi_shea/archive/2009/10/04/pause-the-passive-node-to-apply-sql2005-service-pack-or-hotfix.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=17262" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Cluster/default.aspx">Cluster</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Installation/default.aspx">Installation</category></item><item><title>Database snapshots -- are you using them?</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2009/03/25/database-snapshots-are-you-using-them.aspx</link><pubDate>Wed, 25 Mar 2009 22:09:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:12918</guid><dc:creator>Linchi Shea</dc:creator><slash:comments>24</slash:comments><comments>http://sqlblog.com/blogs/linchi_shea/comments/12918.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/linchi_shea/commentrss.aspx?PostID=12918</wfw:commentRss><description>&lt;P&gt;Database snapshots were introduced in SQL Server 2005, and have been around for several years now. One of the main motivations is that you can create database snapshots to protect&amp;nbsp;your database from user or application errors. It's&amp;nbsp;one more weapon in your DR arsenal.&lt;/P&gt;
&lt;P&gt;But looking at the environments I have worked in for the past few years, I don't recall seeing the feature being used for this purpose at all. In fact, I have not seen it being used for any purpose, period (other than internally by DBCC, etc). Perhaps, people should be using it, but for whatever reason they don't. Perhaps, I'm just hanging around with a wrong crowd.&lt;/P&gt;
&lt;P&gt;So are you using database snapshots? If so, for what purpose?&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=12918" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/General+trends/default.aspx">General trends</category></item><item><title>Large Query Performance and Query Parallelism</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2008/08/24/large-query-performance-and-query-parallelism.aspx</link><pubDate>Sun, 24 Aug 2008 17:32:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:8511</guid><dc:creator>Linchi Shea</dc:creator><slash:comments>12</slash:comments><comments>http://sqlblog.com/blogs/linchi_shea/comments/8511.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/linchi_shea/commentrss.aspx?PostID=8511</wfw:commentRss><description>&lt;P&gt;[&lt;STRONG&gt;2008/08/25&lt;/STRONG&gt;] &lt;EM&gt;&lt;STRONG&gt;This post has been modified significantly to correct some inaccurate statements because I mis-read Joe Chang's post.&lt;/STRONG&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Joe Chang posted some &lt;A href="http://sqlblog.com/blogs/joe_chang/archive/2008/08/17/large-query-performance-from-sql-server-2000-to-2008-32-64-bit.aspx"&gt;interesting results&lt;/A&gt; using the TPC-H queries with the scale factor set to 10. I happened to have done something similar, and naturally noticed a rather significant difference between his results and mine. [2008/08/25: Okay the difference is not as significant as I had thought.]&lt;/P&gt;
&lt;P&gt;My results were obtained on SQL Server 2005 Enterprise x64 Edition running on Windows Server 2003 Enterprise x64 Edition. The test server, whose make and model will remain undisclosed, &amp;nbsp;had four 2.93GHz quad-core Intel Tigerton sockets (Xeon X7350) with 64GB of RAM with 20GB allocated to the SQL Server buffer pool. The TPC-H scale factor was set to 10, and the data were generated with DBGEN from &lt;A href="http://www.tpc.org/"&gt;tpc.org&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;My results are as follows:&lt;/P&gt;
&lt;P&gt;
&lt;TABLE class="" style="WIDTH:333pt;BORDER-COLLAPSE:collapse;" cellSpacing=0 cellPadding=0&gt;






&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl24 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext 0.5pt solid;BORDER-LEFT:windowtext 0.5pt solid;WIDTH:76pt;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl24"&gt;&lt;STRONG&gt;Query&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl29 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext 0.5pt solid;BORDER-LEFT:windowtext;WIDTH:62pt;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" class="xl29"&gt;&lt;STRONG&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;MAXDOP 1&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl29 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext 0.5pt solid;BORDER-LEFT:windowtext;WIDTH:62pt;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" class="xl29"&gt;&lt;STRONG&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;MAXDOP 4&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl29 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext 0.5pt solid;BORDER-LEFT:windowtext;WIDTH:60pt;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" class="xl29"&gt;&lt;STRONG&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;MAXDOP 8&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl29 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext 0.5pt solid;BORDER-LEFT:windowtext;WIDTH:73pt;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" class="xl29"&gt;&lt;STRONG&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;MAXDOP 16&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query1&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;64845&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;17080&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;9373&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;4865&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query2&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;571&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;180&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;110&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;97&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query3&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;17687&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;3272&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1792&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1334&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query4&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;23079&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;3859&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;2293&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1633&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query5&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;34255&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;5040&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;2646&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1935&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query6&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;2250&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;595&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;332&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;204&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query7&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;18299&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;3562&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1754&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1513&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query8&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;9636&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;3245&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;2042&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1809&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query9&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;50470&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;14094&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;7559&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;4460&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query10&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;19363&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;4432&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;2289&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1630&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query11&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;4558&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;674&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;424&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;390&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query12&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;10522&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;3815&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;2718&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;982&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query13&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;26823&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;7577&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;4425&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;2121&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query14&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;2356&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;624&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;357&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;227&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query15&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1705&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1421&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;280&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;170&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query16&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;7960&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;3461&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;2155&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1681&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query17&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1070&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;325&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;220&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;276&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query18&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;68366&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;19719&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;10174&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;5829&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query19&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;2330&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;711&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;441&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;843&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query20&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;968&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;314&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;221&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;695&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query21&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;80858&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;14565&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;8149&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;6072&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl25 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl25"&gt;&lt;STRONG&gt;&lt;EM&gt;tpcH Query22&lt;/EM&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;9418&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;1762&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;986&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" align=right class="xl26"&gt;664&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl24 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:transparent;" class="xl24"&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" class="xl26"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" class="xl26"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" class="xl26"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class=xl26 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:transparent;" class="xl26"&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT:12.75pt;"&gt;
&lt;TD class=xl27 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext 0.5pt solid;BORDER-BOTTOM:windowtext 0.5pt solid;HEIGHT:12.75pt;BACKGROUND-COLOR:yellow;" class="xl27"&gt;&lt;STRONG&gt;Total (second)&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=xl28 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:yellow;" align=right class="xl28"&gt;457&lt;/TD&gt;
&lt;TD class=xl28 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:yellow;" align=right class="xl28"&gt;110&lt;/TD&gt;
&lt;TD class=xl28 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:yellow;" align=right class="xl28"&gt;61&lt;/TD&gt;
&lt;TD class=xl28 style="BORDER-RIGHT:windowtext 0.5pt solid;BORDER-TOP:windowtext;BORDER-LEFT:windowtext;BORDER-BOTTOM:windowtext 0.5pt solid;BACKGROUND-COLOR:yellow;" align=right class="xl28"&gt;39&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;All the numbers in the above table are query elapsed times in milliseconds except the very last line highlighted in yellow, which are in seconds. The last line contains the total elapsed time for Query1 through Query22 for each MAXDOP setting. All the results were obtained with all the database pages cached in the buffer pool. The same TPC-H query stream (i.e. Query 1 through Query 22) was repeated for 10 times with all the results from the first run thrown out, and the max elapsed time and the min elapsed time for each query for each of the subsequent runs were also thrown out before the elapsed times were averaged.&lt;/P&gt;
&lt;P&gt;So what's the difference between Joe's results and mine? &lt;/P&gt;
&lt;P&gt;Although there are some differences in the elapsed times in terms of the absolute numbers,&amp;nbsp;the differences are minor enough to be no cause for alarm, especially when you take into consideration the platform differences and probably some differences in the test setup. &lt;/P&gt;
&lt;P&gt;However, the deline in the elapsed times in my test results&amp;nbsp;is more significant than it is in Joe's results when MAXDOP&amp;nbsp;is changed from 1 through 16. The difference is not as dramatic as I had throught, and initially commented on&amp;nbsp;in the original version of this post (because I was reading the wrong line for whatever reason).&lt;/P&gt;
&lt;P&gt;Given that TPC-H has been around for a long time and all DBMS vendors have tried very hard to optimize their products to performance well on TPC-H, I do not expect SQL Server to be an exception, and am rather pleased to see that it scales very well with MAXDOP on these queries.&lt;/P&gt;
&lt;P&gt;I'm a bit embarrassed that I didn't read Joe's results correctly first time around, but felt that it's time well spent to be able to cross check independent tests results from realistic envrionments.&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=8511" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx">Performance</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Testing/default.aspx">Testing</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Benchmark/default.aspx">Benchmark</category></item><item><title>Performance Impact: Bookmark Lookup is Expensive - Even in Memory</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2008/07/06/performance-impact-bookmark-lookup-is-expensive-even-in-memory.aspx</link><pubDate>Mon, 07 Jul 2008 01:54:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:7679</guid><dc:creator>Linchi Shea</dc:creator><slash:comments>4</slash:comments><comments>http://sqlblog.com/blogs/linchi_shea/comments/7679.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/linchi_shea/commentrss.aspx?PostID=7679</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;It’s well known that bookmark lookup (aka key lookup in case of a clustered index) is not cheap, especially when it comes to retrieving a lot&amp;nbsp;of data. So I’m not going to rehash the pros and cons of bookmark lookup or why bookmark lookup is expensive. But I’ve noticed that when it comes to discussing bookmark lookup, all the literature seems to being focusing on their implications on storage I/Os. There is nothing wrong with that. In practice, it ultimately does come down to the fact that when reading a large amount of data, random I/Os are much more expensive than sequential I/Os, and bookmark lookup tends to incur random I/Os.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;What I’d like to highlight in this post is that even if all or most of the pages are in memory already, bookmark lookup is still very expensive compared to scan. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;To show this is the case, I piggybacked on the test setup described in my last &lt;/FONT&gt;&lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2008/07/04/performance-impact-some-data-points-on-read-ahead.aspx"&gt;&lt;FONT face="Times New Roman" color=#0000ff size=3&gt;post&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Times New Roman" size=3&gt;. Let me briefly recap the test setup. A single table was used, and its definition is as follws:&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="BACKGROUND:#f2f2f2;MARGIN-LEFT:0.25in;mso-background-themecolor:background1;mso-background-themeshade:242;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;CREATE TABLE test ( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int NOT NULL, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; j&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int NOT NULL,&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dt&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; datetime, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filler&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(5000) NOT NULL &lt;BR&gt;)&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Two indexes were created on the table:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="BACKGROUND:#f2f2f2;MARGIN-LEFT:0.25in;mso-background-themecolor:background1;mso-background-themeshade:242;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;CREATE CLUSTERED INDEX cix_test ON test(i);&lt;BR&gt;CREATE INDEX cx_test ON test(j);&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;And the table was populated with 2,000,000 rows with the following INSERT statement in a loop (local variable @i going from 1 to 2,000,000):&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="BACKGROUND:#f2f2f2;MARGIN-LEFT:0.25in;mso-background-themecolor:background1;mso-background-themeshade:242;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;INSERT test(i, j, dt, filler) &lt;BR&gt;SELECT @i, &lt;BR&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;CASE WEHN @i % 2 = 0 THEN @i ELSE 2000000 - @i END,&lt;BR&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;getdate(), &lt;BR&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;'abc'&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Then, the following two queries were separately run multiple times on a server with 32GB of RAM (25GB of which was allocated to the SQL2005 instance buffer pool):&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#f2f2f2;MARGIN:0in 0in 0pt 0.25in;mso-background-themecolor:background1;mso-background-themeshade:242;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;SELECT max(dt) FROM test;&lt;BR&gt;SELECT max(dt) FROM test WITH (index(cx_test));&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;After the second run, all the pages were cached in memory (the table was about 16GB in size). Notice that with the first query SQL Server used clustered index scan to produce the result, whereas with the second query the index hint forced SQL Server to scan the nonclustered index and then use bookmark lookup to produce the result. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;I’ll look at the storage I/O implication of these two access paths in a separate post, but for now what do you think might be the difference in the elapsed time of these two query-processing methods when all the pages were cached in memory?&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The following chart shows the difference:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/7679.ashx"&gt; &lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;For this test, the bookmark lookup method took almost three times as long as did the clustered index scan method. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Why such a huge difference? When all the pages were cached in the buffer pool, we can’t explain the query elapsed time difference with the difference in storage I/O efficiency. We can, however, explain the difference with the difference in the number of pages SQL Server engine must visit in the buffer pool.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The output from SET STATISTICS IO ON for each method is as follows:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;Clustered Index Scan:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#f2f2f2;MARGIN:0in 0in 0pt;mso-background-themecolor:background1;mso-background-themeshade:242;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;Scan count 1, logical reads 2008931, physical reads 0, read-ahead reads 0 …&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;Bookmark Lookup:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#f2f2f2;MARGIN:0in 0in 0pt;mso-background-themecolor:background1;mso-background-themeshade:242;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;Scan count 1, logical reads 8130363, physical reads 0, read-ahead reads 0 …&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Clearly, the access method with bookmark lookup was not efficient, visiting four times as many pages as did the access method with clustered index scan.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Also note that compared with the size of the table, the size of the nonclustered index was insignificant. There were about 5,000 pages in the leaf pages of the nonclustered index, whereas there were 2,000,000 leaf pages in the clustered index. So the cost of processing the query with the nonclustered index was dominated by the bookmark or key lookups.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Of course, what I’ve discussed in this post is probably more academic than practical as you can’t expect all the pages being cached when processing large reporting queries in most real environments, and therefore the real dominate factor is not how many pages SQL Server needs to traverse in memory, but how many pages SQL Server has to bring into memory and how these pages are brought into memory.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;It's not my intention to leave you an impression that I'm picking on the bookmark lookup operation because it's just a bad method to retrieve data. That's not&amp;nbsp;the case at all because for some queries, it is an excellent method. But that's not the focus of this post, and there are plenty of discussions on the advantages of the bookmark lookup operation you can find elsewhere.&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;/FONT&gt;&lt;/o:p&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;Test Environment&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;SQL Server 2005 Enterprise x64 Edition ran on Windows Server 2003 Enterprise x64 Edition with Service Pack 2. The SQL2005 build was 9.0.3239 (i.e. SQL Server 2005 CU7) with 25GB allocated to the buffer pool. The server was a HP BL680 G5 including four 2.4GHz quad-core Xeon E7340 processors (aka Tigerton) with 2x4MB L2 cache and 32GB of RAM.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=7679" width="1" height="1"&gt;</description><enclosure url="http://sqlblog.com/blogs/linchi_shea/attachment/7679.ashx" length="25289" type="image/jpeg" /><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx">Performance</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Query+Processing/default.aspx">Query Processing</category></item><item><title>Performance Impact: Some Data Points on Read-Ahead</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2008/07/04/performance-impact-some-data-points-on-read-ahead.aspx</link><pubDate>Fri, 04 Jul 2008 19:24:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:7660</guid><dc:creator>Linchi Shea</dc:creator><slash:comments>2</slash:comments><comments>http://sqlblog.com/blogs/linchi_shea/comments/7660.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/linchi_shea/commentrss.aspx?PostID=7660</wfw:commentRss><description>&lt;P&gt;In the next series of posts, I'll focus on SQL Server I/O, revisiting some common issues and taking a closer look at some others. In each post and as always, I'll make the case with specific data points from my tests. For the first two posts in this series, let me check out the read-ahead technique used by SQL server.&lt;/P&gt;
&lt;P&gt;Read-ahead is an important I/O optimization technique used by SQL Server.&amp;nbsp; Intuitively, if SQL Server can correctly forecast the need for more pages and read these pages ahead of time when they are needed for query processing in memory, your query is expected to perform better. Bob Dorr in his classic &lt;A href="http://www.microsoft.com/technet/prodtechnol/sql/2000/maintain/sqliobasics.mspx"&gt;SQL Server 2000 I/O Basics&lt;/A&gt; whitepaper has an excellent description on how SQL Server read-ahead works. Every SQL Server professional with any interest at all in the storage engine should read that paper.&lt;/P&gt;
&lt;P&gt;But just how important is the read-ahead technique in query processing? Let's look at some results from an extremely simple test.&lt;/P&gt;
&lt;P&gt;First of all, a single table was used in the test, and here is the definition:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;CREATE TABLE test ( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int NOT NULL, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; j&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int NOT NULL,&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dt&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; datetime, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filler&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(5000) NOT NULL &lt;BR&gt;)&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I then created a clustered index on the i column (for this test column j was not used and you can ignore it):&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;CREATE CLUSTERED INDEX cix_test ON test(i);&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;And the table was populated with 2,000,0000 rows with the following INSERT statement in a loop with @i going from 1 to 2,000,000:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;INSERT test(i, j, dt, filler) &lt;BR&gt;SELECT @i, CASE WEHN @i % 2 = 0 THEN @i ELSE 2000000 - @i END, getdate(), 'abc'&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;With the statistics updated, I then ran the following SELECT query in two test scenarios:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;DBCC DROPCLEANBUFFERS; &lt;BR&gt;go &lt;BR&gt;SELECT max(dt) FROM test;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The two test scenarios are as follows:&lt;/P&gt;
&lt;TABLE class="" cellSpacing=2 cellPadding=4&gt;

&lt;TR&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;&lt;U&gt;Test Scenario&lt;/U&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;&lt;U&gt;Description&lt;/U&gt;&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;Read-ahead enabled&lt;/TD&gt;
&lt;TD class=""&gt;This is the default SQL Server behavior.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;Read-ahead disabled&lt;/TD&gt;
&lt;TD class=""&gt;Read-ahead was disabled with trace flag 652: DBCC TRACEON(-1, 652)&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;
&lt;P&gt;First, let's look at the elapsed time of the above SELECT query in the two scenarios (the numbers reported in the following table are averages over several test runs):&lt;/P&gt;
&lt;TABLE class="" cellSpacing=2 cellPadding=4&gt;

&lt;TR&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;&lt;U&gt;Test Scenario&lt;/U&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;&lt;U&gt;Elapsed Time of SELECT (second)&lt;/U&gt;&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;Read-ahead enabled&lt;/TD&gt;
&lt;TD class=""&gt;80&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;Read-ahead disabled&lt;/TD&gt;
&lt;TD class=""&gt;210&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;
&lt;P&gt;In both scenarios, the SELECT query was correctly processed with a clustered index scan. When read-ahead was disabled, the clustered index scan took almost three times as long as did the clustered index scan when read-ahead was not disabled. For this query, the performance difference was astounding.&lt;/P&gt;
&lt;P&gt;I don't have access to the source code that controls read-ahead so I can't tell exactly why and how it made such a huge difference from the code logic perspective. However, from Bob Dorr's description in the SQL Server 2000 I/O Basics whitepaper, it's rather clear that SQL Server read-ahead is quite aggressive in exploiting the performance capacity of the storage I/O subsystem.&amp;nbsp; So we can turn to observing the storage I/O behavior for explanation. The following table summarizes the values of the key I/O counters observed during the test runs:&lt;/P&gt;
&lt;TABLE class="" cellSpacing=2 cellPadding=4&gt;

&lt;TR&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;&lt;U&gt;I/O Counter&lt;/U&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;&lt;U&gt;Value When Read-ahead is Enabled&lt;/U&gt;&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;&lt;U&gt;Value When Read-ahead is Disabled&lt;/U&gt;&lt;/STRONG&gt; &lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;Bytes/Read&lt;/TD&gt;
&lt;TD class=""&gt;&amp;gt; 350KB/read&lt;/TD&gt;
&lt;TD class=""&gt;~ 8KB/read&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;Megabytes/sec&lt;/TD&gt;
&lt;TD class=""&gt;180 ~ 200MB/sec&lt;/TD&gt;
&lt;TD class=""&gt;~ 80MB/sec&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;SQL Server Readahead&lt;/TD&gt;
&lt;TD class=""&gt;~20,000 readahead pages/sec&lt;/TD&gt;
&lt;TD class=""&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;
&lt;P&gt;Clearly, with read-ahead, SQL Server was able to take advantage of large sized I/Os (e.g. ~350KB per read). Large-sized I/Os are generally much more efficient than smaller-sized I/Os, especially when you actually need all the data read from the storage as was the case with the test query. From the table above, it's evident that the read throughput was significantly higher when read-ahead was enabled than it was when read-ahead was disabled. In other words, without read-ahead, SQL Server was not pushing the storage I/O subsystem hard enough, contributing to a significantly longer query elapsed time. &lt;/P&gt;
&lt;P&gt;That is, the table was about 16,000MB in size. At ~200MB/sec, it would take about 80 seconds to read 16,000MB, and at ~80MB/sec, it would take about 200 seconds to read the same amount of data. And these numbers (i.e. 80 seconds and 200 seconds) match nicely&amp;nbsp;the recorded query elaped times which are reported in the second table above.&lt;/P&gt;
&lt;P&gt;In the next post, I'll check out the impact of disabling read-ahead on bookmark or key lookups when a nonclustered index is used.&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=7660" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx">Performance</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Storage/default.aspx">Storage</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item><item><title>Dedicated Admin Connection</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2008/05/20/dedicated-admin-connection.aspx</link><pubDate>Tue, 20 May 2008 16:31:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:6884</guid><dc:creator>Linchi Shea</dc:creator><slash:comments>15</slash:comments><comments>http://sqlblog.com/blogs/linchi_shea/comments/6884.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/linchi_shea/commentrss.aspx?PostID=6884</wfw:commentRss><description>&lt;P&gt;Dedicated Admin Connection (DAC) is one of the highly touted features introduced in SQL Server 2005. Now that it has been around for a few years, I wonder how it is actually being used or whether it's being used at all in the real world.&lt;/P&gt;
&lt;P&gt;I have not run into any real production scenarios where I'm forced to use DAC. But that may just be due to my own narrow exposure to SQL Server problems. If you have used it to solve real problems (not just for testing or folling around), I'd very much like to know what kind of problems they were.&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6884" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Tools/default.aspx">Tools</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+connectivity/default.aspx">SQL Server connectivity</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item><item><title>SQL Server Checkpoint I/O Behavior</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2008/01/19/sql-server-checkpoint-i-o-behavior.aspx</link><pubDate>Sat, 19 Jan 2008 07:11:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:4595</guid><dc:creator>Linchi Shea</dc:creator><slash:comments>5</slash:comments><comments>http://sqlblog.com/blogs/linchi_shea/comments/4595.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/linchi_shea/commentrss.aspx?PostID=4595</wfw:commentRss><description>&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Andrew Kelly in a recent post &lt;A title=http://sqlblog.com/blogs/andrew_kelly/archive/2008/01/13/getting-back-to-the-basics-with-i-o.aspx href="http://sqlblog.com/blogs/andrew_kelly/archive/2008/01/13/getting-back-to-the-basics-with-i-o.aspx"&gt;here&lt;/A&gt; advised visiting/revisiting the SQL Server I/O basics, and I completely agree. A firm grasp of the basics can make it easy to understand some system behaviors that&amp;nbsp;otherwise may be puzzling at times.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;A question that&amp;nbsp;is often asked is how SQL Server&amp;nbsp;performs the I/O writes in its checkpoints. More specifically, some folks are puzzled at why SQL Server checkpoints don't seem to write to disks using a constant block size.&amp;nbsp;For the basics, Bob Dorr has a detailed description on the checkpoint I/O behavior in his two&amp;nbsp;articles: &lt;A href="http://www.microsoft.com/technet/prodtechnol/sql/2000/maintain/sqlIObasics.mspx"&gt;SQL Server 2000 I/O Basics&lt;/A&gt; and &lt;A href="http://www.microsoft.com/technet/prodtechnol/sql/2005/iobasics.mspx"&gt;SQL Server I/O Basics Chapter 2&lt;/A&gt;. You can read these articles for all the information. What I want to highlight is that, "SQL Server 2005 extends the capability of WriteMultiple up to 32 pages (256 KB)." And SQL Server checkpoints make calls to this WriteMultiple internal routine.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Now, note that one of the most fundamental disk I/O rules is that large sequential I/Os are more efficient than small random I/Os. So if SQL Server can write 32 pages in a single I/O, it would try to do it.&amp;nbsp;As a matter of&amp;nbsp;fact, as Bob Dorr mentioned in his article, SQL Server 2005 has gotten more aggressive in&amp;nbsp;finding&amp;nbsp;as many contiguous pages as possible and lumping them into a single I/O request.&amp;nbsp;If SQL Server can't find contiguous pages, it would write one page at a time in its checkpoints, and that would be very inefficient.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;To see this in action, you can run a simple test yourself. First, create the following table:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;create table PageCheck (&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;c1 int identity,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;c2 char(5000) not NULL&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;And then populate the table with one million contiguous pages:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;declare @i int&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;set @i = 1&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;begin tran&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;while @i &amp;lt;= 1000000&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;begin&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;if @i % 100 = 0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;begin&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&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; &lt;/SPAN&gt;commit tran&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&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; &lt;/SPAN&gt;begin tran&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;end&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;insert PageCheck(c2) values('&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;')&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;set @i = @i + 1&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;end&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;commit tran&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Now effectively disable automatic checkpoints:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;sp_configure 'recovery interval', 32767&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;go&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;reconfigure with override&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Case 1&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Run the following SQL to update the first 500,000 rows (corresponding to 500,000 contiguous dirty pages):&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;update PageCheck&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;set c2 = 'abc'&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;where c1 &amp;lt;= 500000&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Now we are ready to see how a checkpoint may behave by doing a manual checkpoint and observing the Avg. Disk Bytes/Write performance counter. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;The Avg. Disk Bytes/Write counter would show that each request would be around 256K, or 32 8K pages. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Case 2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;To see how a checkpoint behaves when there is no contiguous dirty pages, run the following SQL to update every other page:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;update PageCheck&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;set c2 = 'xyz'&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;where c1 % 2 = 0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Do a manual checkpoint now, and observe the Avg. Disk Bytes/Write counter. The counter value would be around 8K.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;The first case represents the best scenario for checkpoint I/O performance, and on my machine the manual checkpoint took ~21 seconds to complete. The second case however represents the worst scenario, and on my machine the manual checkpoint took ~71 seconds to complete. The difference was more than three times.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=4595" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx">Performance</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Storage/default.aspx">Storage</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item><item><title>A Rose By Any Other Name</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2007/11/20/a-rose-by-any-other-name.aspx</link><pubDate>Tue, 20 Nov 2007 20:04:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:3442</guid><dc:creator>Linchi Shea</dc:creator><slash:comments>8</slash:comments><comments>http://sqlblog.com/blogs/linchi_shea/comments/3442.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/linchi_shea/commentrss.aspx?PostID=3442</wfw:commentRss><description>&lt;P&gt;Regardless of the DBMS make or model, the transaction throughput curve of a database system is often shaped like a trapezoid. As the load level goes up initially, so does the transaction throughput. As the load level continues to go up, the transaction throughput will reach a plateau. After the load level is cranked up still further, the transaction throughput will inevitably start to drop and may eventually come to a&amp;nbsp; halt.&lt;/P&gt;
&lt;P&gt;With respect to the throughput drop under severe load, two questions are interesting: (1) what is the cause of the drop? and (2) what can we do to delay the drop until an even higher load level?&lt;/P&gt;
&lt;P&gt;The answers are of course dependent on the nature of the workload, the system configurations, and a host of other factors. &lt;/P&gt;
&lt;P&gt;So rather than trying to address the questions in general, let's look at one specific type of tests I often perform, which is to stress the processors, memory, and their interconnect of a server with a SQL Server read-only workload that effectively caches all the data pages in memory. In other words, this workload takes the disk I/Os out of the equation.&lt;/P&gt;
&lt;P&gt;As expected and with no exception, I would see the transaction throughput start to drop--sometimes rather dramatically--as I increase the load level beyond saturation. When this may happen often correlates nicely with a dramatic increase in waits on &lt;I&gt;Thread-safe memory objects waits&lt;/I&gt; under &lt;I&gt;SQLServer:Wait Statistics&lt;/I&gt;. Unfortunately, this wait counter is documented with a rather useless tautology in that the explanation more or less repeats what the name already suggests without adding useful information. (BTW, the explanation is "Statistics for processes waiting on thread-safe memory allocators"). So,&amp;nbsp; from looking at the wait stats, I can't really tell what wait or waits are killing the transaction throughput.&lt;/P&gt;
&lt;P&gt;The point I want to illustrate, however, is the dramatic impact of a change to the workload--a change that merely gives the stored procedures different names.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Original workload:&lt;/B&gt; The database calls of the workload calls are even distributed between two stored procedures, spOrderStatus and spStockLevel. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Modified workload&lt;/B&gt;: In the same database, I created 100 stored procedures: spOrderStatus_1 through spOrderStatus_100, that are identical to spOrderStatus except the names. Similarly, I created another 100 stored procedures: spStockLevel_1 through spStockLevel_100, that are identical to spStockLevel except the names. I then modified the original workload to distribute the database calls evenly among spOrderStatus_1 through spOrderStatus_100 and spStockLevel_1 through spStockLevel_100.&lt;/P&gt;
&lt;P&gt;With the modified workload, the same database was able to sustain the peak throughput for significantly higher load level (i.e. more users). The following chart summarizes the throughput behavior between the original workload and the modified workload on the test server:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/3442.ashx"&gt; &lt;/P&gt;
&lt;P&gt;I didn't specifically test how many identical but differently named stored procedures I had to create to see the impact on the transaction throughput. 100 for each stored procedure was picked randomly. &lt;/P&gt;
&lt;P&gt;Note that this is a known technique and is used in some of the published SQL Server TPC-C tests. For instance, in the best &lt;A href="http://www.tpc.org/tpcc/results/tpcc_result_detail.asp?id=105112801"&gt;SQL Server TPC-C results obtained on HP Superdome&lt;/A&gt;, 32 New_Order stored procedures are created with 32 different names but identical code inside. Stored procedures with different names but identical code are also created for several other transactions.&lt;/P&gt;
&lt;P&gt;So, a rose by a different name may just smell better.&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=3442" width="1" height="1"&gt;</description><enclosure url="http://sqlblog.com/blogs/linchi_shea/attachment/3442.ashx" length="5378" type="image/gif" /><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx">Performance</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Waits/default.aspx">Waits</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Best+Practices/default.aspx">Best Practices</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item><item><title>Nondeterministic UPDATE</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2007/11/13/nondeterministic-update.aspx</link><pubDate>Tue, 13 Nov 2007 19:15:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:3312</guid><dc:creator>Linchi Shea</dc:creator><slash:comments>2</slash:comments><comments>http://sqlblog.com/blogs/linchi_shea/comments/3312.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/linchi_shea/commentrss.aspx?PostID=3312</wfw:commentRss><description>&lt;P&gt;Under the description for UPDATE in SQL Server &lt;A href="http://msdn2.microsoft.com/en-us/library/aa260662(SQL.80).aspx"&gt;2000&lt;/A&gt; and &lt;A href="http://msdn2.microsoft.com/en-us/library/ms177523.aspx"&gt;2005&lt;/A&gt; Books Online, you can find the following statement (thanks to SQL Server MVP Steve Kass for pointing me to this passage):&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The results of an UPDATE statement are undefined if the statement includes a FROM clause that is not specified in such a way that only one value is available for each column occurrence that is updated, that is if the UPDATE statement is not deterministic.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;BOL goes on to give a simple example of such an UPDATE. However, the example doesn't give you a real feel for the nondeterministic behavior. Although the result is supposed to be undefined and indeed you don't know&amp;nbsp;what value UPDATE will end up assigning, the result does come out consistently the same no matter how many times you execute it. At least during my limited number of test runs, UPDATE seems to always pick the first value. But of course you can't count on that because a different execution plan may pick a different value.&lt;/P&gt;
&lt;P&gt;Still, it would be nice to see a nondeterministic UPDATE statement actually picks a different value to drive it home that you should not use it in your app, unless of course your app logic wants to take advantage of this particular non-determinism (which is difficult to imagine).&lt;/P&gt;
&lt;P&gt;Recently, however, I happened to run into an interesting case where the nondeterministic behavior of UPDATE can be easily reproduced on a multi-core server when query parallelism is used. Here's the script to see the behavior.&lt;/P&gt;
&lt;P&gt;First, run the following script to create two tables and a stored procedure in any user database on a SQL Server 2005 instance:&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#dddddd;"&gt;&lt;PRE&gt;CREATE TABLE t1 (
	c1 int         NULL,
	c2 varchar(50) NULL,
	rate int       NULL
)
go
CREATE INDEX c1_ind ON t1 (c1)
go

CREATE TABLE t2 (
	c1 int           NULL,
	c2 varchar(50)   NULL,
	rate int         NOT NULL
)
go

drop proc testProc
go
create proc testProc
as
set nocount on
begin tran
  UPDATE t1
     SET rate = t2.rate
    FROM t1 With (Index (c1_ind)), t2
   WHERE t1.c1 = t2.c1
     and t1.c2 = t2.c2

  SELECT 'count_0' = count(*) FROM t1 WHERE rate = 0;
  SELECT 'count_1' = count(*) FROM t1 WHERE rate = 1;
  SELECT 'rate_sum' = sum(rate) FROM t1
rollback tran
go&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Second, populate the two tables with data using the following script:&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#e8e8e8;"&gt;&lt;PRE&gt;WITH tmp (c1, c2,c3) as (
    SELECT 1,1,1
    UNION ALL
    SELECT cast(rand(c3)*1000000 as int)%200, 
           cast(rand(c3)*1000000 as int)%200, 
           c3 + 1
      FROM tmp
     WHERE c3 &amp;lt; 100000
)
INSERT t1
SELECT c1, CAST(c2 as varchar(50)), NULL
  FROM tmp
OPTION (maxrecursion 0);

WITH tmp (c1, c2, c3) as (
    SELECT 0,0,0
    UNION ALL
    SELECT c1 + 1, c2 + 1, c3 + 1
      FROM tmp
     WHERE c1 &amp;lt; 200
)
INSERT t2
SELECT cast(c1 as char(6)), 
       cast(c2 as varchar(50)), 
       0                         -- c3 value = 0
  FROM tmp
OPTION (maxrecursion 0);

-- give each c1 value a second c3 value = 1
INSERT t2
SELECT c1, c2, 1
  FROM t2;
go
&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Finally, run the stored procedure multiple times to see that different results are produced: &lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#e5e5e5;"&gt;EXEC testProc;&lt;/DIV&gt;
&lt;P&gt;Apparently, nondeterminism in query processing gives rise to the different results. A few observations are noteworthy:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The non-determinstic behavior is not a result of different query execution plan. At least, the reported execution plan&amp;nbsp;remains the same for all my test runs.&lt;/LI&gt;
&lt;LI&gt;If you disable query parallelism by setting &lt;U&gt;max degree of parallelism&lt;/U&gt; to 1, the stored procedure will produce the same results.&lt;/LI&gt;
&lt;LI&gt;On a SQL Server 2000 instance, you probably won't get a parallel plan, and thus won't see different results.&lt;/LI&gt;
&lt;LI&gt;The size of the table t1 is significant. On my test server, populating table t1 with 70,000 still leads to a parallel query plan, thus different results in multiple executions of the stored procedure. But if I only populate the table with 50,000 rows, I don't get an query parallelism, and I get consistent results. So SQL Server query optimizer is sensitive to the table size in deciding whether to use a parallel plan.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=3312" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Best+Practices/default.aspx">Best Practices</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/T-SQL/default.aspx">T-SQL</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item><item><title>Performance Impact: The Potential Cost of Read_Committed_Snapshot</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2007/10/05/performance-impact-the-potential-cost-of-read-committed-snapshot.aspx</link><pubDate>Fri, 05 Oct 2007 03:49:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:2883</guid><dc:creator>Linchi Shea</dc:creator><slash:comments>4</slash:comments><comments>http://sqlblog.com/blogs/linchi_shea/comments/2883.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/linchi_shea/commentrss.aspx?PostID=2883</wfw:commentRss><description>&lt;P&gt;In response to my previous blog post--&lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2007/10/01/performance-impact-setting-a-database-to-read-only.aspx"&gt;Performance Impact: Setting a Database to Read Only&lt;/A&gt;, Shailesh Khanal mentioned that he observed significant performance degradation from&amp;nbsp;READ COMMITTED SNAPSHOT OFF to ON for a read-only workload. This&amp;nbsp;is counter intuitive since there is nothing in the version store if only SELECT statements are running, and the overhead of turning READ COMMITTED SNAPSHOT ON without maintaining any versions shouldn't be that high.&lt;/P&gt;
&lt;P&gt;So I decided to conduct some tests myself with a different read-only workload on SQL Server 2005 SP2 (9.00.3042) Enterprise Edition. The read-only workload was the same as that described in&amp;nbsp;the previous blog post--&lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2007/10/01/performance-impact-setting-a-database-to-read-only.aspx"&gt;Performance Impact: Setting a Database to Read Only&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;My results were mixed. On one hand, I confirmed Shailesh Khanal's observation that turning READ COMMITTED SNAPSHOT ON caused significant performance degradation. It's interesting to note that performance degradation was all observed on 64-bit 16-way machines. On the other hand, I didn't always observe heavy performance penalty when turning READ COMMITTED SNAPSHOT ON. On a 32-bit 4-way machine, I didn't see any degradation at all. The following two charts summarize&amp;nbsp;my results:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/2883.ashx"&gt; &lt;/P&gt;
&lt;P&gt;In Fig 1, the performance penalty of READ_COMMITTED_SNAPSHOT&amp;nbsp;for a read-only workload was astounding. Just by turning READ_COMMITTED_SNAPSHOT OFF, the transaction throughput gained a whopping ~60%. This was observed in repeated test runs, and on two different platforms. The common characteristics of these two platforms included: (1) the SQL Server 2005 instances were both x64 running on Windows 2003 x64, and (2) the servers&amp;nbsp;both had 16 cores.&lt;/P&gt;
&lt;P&gt;That's bad news. But there&amp;nbsp;was good news. On a different platform, repeating the same test led to very different results as summarized in Fig 2 above. If there is any difference between the two lines in Fig 2, turning READ_COMMITTED_SNAPSHOT ON appears to have produced slightly better throughput, though the difference should probably be considered insignificant and within the margin of error. This test platform was 32-bit SQL Server 2005 running on 32-bit Windows 2003, and the server had 4 cores.&lt;/P&gt;
&lt;P&gt;Now, I don't know the test environment that Shailesh Khanal used&amp;nbsp;to obtain his results. But from my own tests,&amp;nbsp;I'd venture a conjecture that the performance difference could be attributed to the difference between 64-bit and 32-bit, not the hardware difference between 4 cores and 16 cores. And I'd further venture to suggest that the performance degradation from READ_COMMITTED_SNAPSHOT OFF to ON in the case of 64-bit and read-only workload was most likely due to a bug because the degradation was simply too large to be a feature or by design.&lt;/P&gt;
&lt;P&gt;So is there any practical significance to all this?&lt;/P&gt;
&lt;P&gt;Clearly, you need to use READ_COMMITTED_SNAPSHOT with caution in performance tuning. Best practice recommends that you consider using it if contention is costing you throughput. For read-only workloads, there is no reader/writer contention for READ_COMMITTED_SNAPSHOT to help avoid, and there is no statement-level data consistency problem for it to prevent.&lt;/P&gt;
&lt;P&gt;The other lesson is that you really can't assume anything, even if it intuitively makes sense. You should always confirm it through testing, if possible.&lt;/P&gt;
&lt;P&gt;Finally, there could be a scenario where you have a read/write workload, and READ_COMMITTED_SNAPSHOT improves its performance by resolving your reader/write contention problem, but at the same time degrades the performance of its read-only queries. Overall, you may or may not see a net gain. Again, you'll have to run tests to be sure one way or another.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=2883" width="1" height="1"&gt;</description><enclosure url="http://sqlblog.com/blogs/linchi_shea/attachment/2883.ashx" length="11210" type="image/gif" /><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx">Performance</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/Best+Practices/default.aspx">Best Practices</category><category domain="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item></channel></rss>