<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Linchi Shea</title><subtitle type="html" /><id>http://sqlblog.com/blogs/linchi_shea/atom.aspx</id><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/default.aspx" /><link rel="self" type="application/atom+xml" href="http://sqlblog.com/blogs/linchi_shea/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.61129.1">Community Server</generator><updated>2008-02-12T00:43:00Z</updated><entry><title>SQL Server 2008 Page Compression: Performance impact on table scans</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/05/16/sql-server-2008-page-compression-performance-impact-on-table-scans.aspx" /><link rel="enclosure" type="image/gif" length="7086" href="http://sqlblog.com/blogs/linchi_shea/attachment/6835.ashx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/05/16/sql-server-2008-page-compression-performance-impact-on-table-scans.aspx</id><published>2008-05-17T01:28:00Z</published><updated>2008-05-17T01:28:00Z</updated><content type="html">&lt;P&gt;My previous &lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2008/05/12/sql-server-2008-page-compression-performance-impact-on-inserts.aspx"&gt;post&lt;/A&gt; shows that data compression may not come for free, although hopefully by the RTM time the adverse performance impact on inserts will have been reduced significantly. In this post, I want to show you that data compression can enhance read performance. Intuitively, data compression&amp;nbsp;may reduce the number of pages SQL Server must&amp;nbsp;read into memory from disk, and the savings in terms of the number of pages can be significant, and therefore there may be a positive impact on reads. &lt;/P&gt;
&lt;P&gt;To continue our tradition of letting data points do the talking, I ran the following simple script with the customer table when (1) it was page compressed and when (2) it was not page compressed. This was the same customer table I described in an earlier post on &lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2008/05/05/sql-server-2008-page-compression-using-multiple-processors.aspx"&gt;page compression and multiple processors&lt;/A&gt;.&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#cccccc;"&gt;&lt;FONT face="Courier New"&gt;dbcc dropcleanbuffers;&lt;BR&gt;declare @dt datetime;&lt;BR&gt;select @dt = getdate();&lt;BR&gt;&lt;BR&gt;select avg(c_balance) from customer;&lt;BR&gt;&lt;BR&gt;select datediff(second, @dt, getdate());&lt;BR&gt;go&lt;BR&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;P&gt;Note that there was no index on the c_balance column, and I verified that the actual execution plan was a table scan (well a clustered index scan). DBCC DROPCLEANBUFFER was included to ensure pages were read from disk, not already cached. The following chart summarizes the results.&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/6835.ashx"&gt; &lt;/P&gt;
&lt;P&gt;Wow! The elapsed time difference between the compressed data and uncompressed data&amp;nbsp;was huge. It took 52 seconds to scan the table when it's not compressed,&amp;nbsp;but it took only 3 seconds when the table was compressed. Note that when uncompressed, the table had 2264 pages, and when compressed it had 534 pages.&lt;/P&gt;
&lt;P&gt;Two more points to note: First, I did not try to explain why the improvement in table scan performance seemed to be disproportional to the reduction in the table size as the result of page compression. But I did run these tests many times to make sure I was not going to give you incorrect data. Second, I would caution you not to get too hung up on these specific numbers. As they often say, your mileage may vary. Instead, focus on the big picture impression that page compression may give your reporting queries a performance boost. In a real app, life is not so simple, and you would have to strike a balance between better reporting queries and potentially longer batch/data feed processing time when you consider page compression.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=SQL Server 2008 Page Compression: Performance impact on table scans&amp;amp;body=Seen on SQLblog.com: %0A%0A%09SQL Server 2008 Page Compression: Performance impact on table scans%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/05/16/sql-server-2008-page-compression-performance-impact-on-table-scans.aspx" target="_blank" title = "Email SQL Server 2008 Page Compression: Performance impact on table scans"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/16/sql-server-2008-page-compression-performance-impact-on-table-scans.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Performance+impact+on+table+scans" target="_blank" title = "Submit SQL Server 2008 Page Compression: Performance impact on table scans to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/16/sql-server-2008-page-compression-performance-impact-on-table-scans.aspx&amp;amp;phase=2" target="_blank" title = "Submit SQL Server 2008 Page Compression: Performance impact on table scans to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/16/sql-server-2008-page-compression-performance-impact-on-table-scans.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Performance+impact+on+table+scans" target="_blank" title = "Submit SQL Server 2008 Page Compression: Performance impact on table scans to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/16/sql-server-2008-page-compression-performance-impact-on-table-scans.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Performance+impact+on+table+scans" target="_blank" title = "Submit SQL Server 2008 Page Compression: Performance impact on table scans to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/16/sql-server-2008-page-compression-performance-impact-on-table-scans.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Performance+impact+on+table+scans&amp;amp;;top=1" target="_blank" title = "Add SQL Server 2008 Page Compression: Performance impact on table scans to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6835" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Performance" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx" /><category term="SQL Server 2008" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2008/default.aspx" /><category term="Data Compression" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Data+Compression/default.aspx" /></entry><entry><title>SQL Server 2008 Page Compression: Performance impact on inserts</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/05/12/sql-server-2008-page-compression-performance-impact-on-inserts.aspx" /><link rel="enclosure" type="image/gif" length="8414" href="http://sqlblog.com/blogs/linchi_shea/attachment/6773.ashx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/05/12/sql-server-2008-page-compression-performance-impact-on-inserts.aspx</id><published>2008-05-13T02:49:00Z</published><updated>2008-05-13T02:49:00Z</updated><content type="html">&lt;P&gt;Before I begin, let me be very clear that the results I report in this post were obtained with SQL Server 2008 CTP6. Microsoft is still working on improving the performance of data compression. And in particular, the performance of inserting into a compressed table is expected to be significantly enhanced in SQL Server 2008 RTM.&lt;/P&gt;
&lt;P&gt;In my previous &lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2008/05/11/sql-server-2008-page-compression-compression-ratios-from-real-world-databases.aspx"&gt;post&lt;/A&gt;, I have shown that data compression can result in significant savings in storage space. In this post, I want to highlight the fact that not everything comes for free. Let's take a look at inserting into a B-tree table, i.e. a table with a clustered index. What is the performance impact of page compression on inserts? &lt;/P&gt;
&lt;P&gt;Note that you must use TABLOCK hint for pages to receive page-level compression when the pages of a heap table are being populated with the INSERT statement. So, heap tables are much less interesting, and&amp;nbsp;I'll hence focus only on B-tree tables. &lt;/P&gt;
&lt;P&gt;In my tests, I ran the following script:&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#cccccc;"&gt;&lt;FONT face="Courier New"&gt;truncate table customer2;&lt;BR&gt;-- enable page compression&lt;BR&gt;alter table customer2 rebuild with (data_compression=page);&lt;BR&gt;go&lt;BR&gt;declare @dt datetime;&lt;BR&gt;select @dt = getdate();&lt;BR&gt;insert customer2 select * from customer;&lt;BR&gt;select 'insert into customer2 with compression', datediff(second, @dt, getdate());&lt;BR&gt;go&lt;BR&gt;truncate table customer2;&lt;BR&gt;-- disable compression&lt;BR&gt;alter table customer2 rebuild with (data_compression=none);&lt;BR&gt;go&lt;BR&gt;declare @dt datetime;&lt;BR&gt;select @dt = getdate();&lt;BR&gt;insert customer2 select * from customer;&lt;BR&gt;select 'insert into customer2 without compression', datediff(second, @dt, getdate());&lt;BR&gt;go&lt;BR&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;P&gt;The script measures the difference in the elapsed time of inserting 3,000,000 rows into (1) an empty table when page compression&amp;nbsp;is enabled, and (2) an empty table when no data compression&amp;nbsp;is enabled. The script was run multiple times to ensure that the elapsed times recorded were consistent. The following chart shows the results:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/6773.ashx"&gt; &lt;/P&gt;
&lt;P&gt;Clearly, the impact of page compression on inserts was rather significant in the tests. Without data compression, inserting 3,000,000 rows took ~80 seconds, whereas it took 217 seconds when page compression was enabled on the target B-tree table. No free lunch!&lt;/P&gt;
&lt;P&gt;Again, these numbers were obtained with SQL Server 2008 CTP6, a work in progress build. I'll re-run the test once SQL Server 2008 RTM is released.&lt;/P&gt;
&lt;P&gt;Now that I have shown that there can be performance penalty in using data compression, next time I'll show that data compression can also help&amp;nbsp;improve your performance.&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=SQL Server 2008 Page Compression: Performance impact on inserts&amp;amp;body=Seen on SQLblog.com: %0A%0A%09SQL Server 2008 Page Compression: Performance impact on inserts%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/05/12/sql-server-2008-page-compression-performance-impact-on-inserts.aspx" target="_blank" title = "Email SQL Server 2008 Page Compression: Performance impact on inserts"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/12/sql-server-2008-page-compression-performance-impact-on-inserts.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Performance+impact+on+inserts" target="_blank" title = "Submit SQL Server 2008 Page Compression: Performance impact on inserts to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/12/sql-server-2008-page-compression-performance-impact-on-inserts.aspx&amp;amp;phase=2" target="_blank" title = "Submit SQL Server 2008 Page Compression: Performance impact on inserts to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/12/sql-server-2008-page-compression-performance-impact-on-inserts.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Performance+impact+on+inserts" target="_blank" title = "Submit SQL Server 2008 Page Compression: Performance impact on inserts to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/12/sql-server-2008-page-compression-performance-impact-on-inserts.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Performance+impact+on+inserts" target="_blank" title = "Submit SQL Server 2008 Page Compression: Performance impact on inserts to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/12/sql-server-2008-page-compression-performance-impact-on-inserts.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Performance+impact+on+inserts&amp;amp;;top=1" target="_blank" title = "Add SQL Server 2008 Page Compression: Performance impact on inserts to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6773" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Performance" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx" /><category term="SQL Server 2008" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2008/default.aspx" /><category term="Data Compression" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Data+Compression/default.aspx" /></entry><entry><title>SQL Server 2008 Page Compression: Compression ratios with real-world databases</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/05/11/sql-server-2008-page-compression-compression-ratios-from-real-world-databases.aspx" /><link rel="enclosure" type="image/gif" length="16981" href="http://sqlblog.com/blogs/linchi_shea/attachment/6750.ashx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/05/11/sql-server-2008-page-compression-compression-ratios-from-real-world-databases.aspx</id><published>2008-05-11T23:20:00Z</published><updated>2008-05-11T23:20:00Z</updated><content type="html">&lt;P&gt;In my &lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2008/05/05/sql-server-2008-page-compression-using-multiple-processors.aspx"&gt;previous post&lt;/A&gt; on data compression, I looked at how rebuilding a table with page compression works with multiple processors via the MAXDOP option. In this post, I'll focus on what compression ratios&amp;nbsp;I have seen in the real-world databases. Now, if you understand how SQL Server 2008 data compression works, you know that what compression ratio you may get really depends on to what extent SQL Server can find duplicate values on the data/index pages. Consequently, one real-world database can have a very high compression ratio while another may have a very low compression ratio: there is no typical compression ratio to expect.&lt;/P&gt;
&lt;P&gt;That said, it is still interesting to&amp;nbsp;report what compression ratios I have seen with real customer databases instead of 'cooked' data. Before I give the results, let me define what&amp;nbsp;I mean by compression ratio:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT face="Courier New"&gt;&lt;B&gt;Compression Ratio = Uncompressed Size / Compressed Size&lt;/B&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;To see what kind of compression ratios I may run into with real-world databases, I randomly selected 14 customer databases. IN this blog post, these databases have been renamed to DB1, DB2, ..., DB13, and DB14 to&amp;nbsp;shield their identities. For each database, the following steps were performed:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Record the data size of sp_spaceused for the database. This is the uncompressed data size.&lt;/LI&gt;
&lt;LI&gt;For each user table in the database, rebuild it with page compression. This was done by generating and executing a script that contains the following ALTER TABLE statement for each table:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT face="Courier New"&gt;alter table &amp;lt;the_table&amp;gt; rebuild with (data_compression=page, maxdop=8);&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;Record the data size of sp_spaceused for the database. This is the compressed data size.&lt;/LI&gt;
&lt;LI&gt;For each user table in the database, rebuild the table with no compression, which effectively decompresses the table. This was done by generating and executing a script that contains the following ALTER TABLE statement for each table:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT face="Courier New"&gt;alter table &amp;lt;the_table&amp;gt; rebuild with (data_compression=none, maxdop=8);&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;Record the data size of sp_spaceused for the database. This is the decompressed data size.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The data size obtained in Step 3 was used as database compressed size, and the data size obtained in Step 5 was used as the database uncompressed size. The data size obtained in Step 1 was not used because it may be polluted by fragmentation. If we used the data size from Step 1, we could potentially be using a size that was inflated by fragmentation, resulting in an incorrectly higher compression ratio.&lt;/P&gt;
&lt;P&gt;The following two charts summarize the results:&lt;/P&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/6750.ashx"&gt; 
&lt;P&gt;The top chart includes the three database space measures mentioned above. As you can see, fragmentation was not a significant factor for these databases since the uncompressed size and decompressed size were quite close for each database. As it turned out, these databases were regularly maintained, including rebuilding clustered indexes, it's no surprise that there wasn't any serious fragmentation.&lt;/P&gt;
&lt;P&gt;To highlight the compressed ratios for these databases, the bottom chart plots the compression ratios. So for these databases, the compression ratios--obtained using SQL Server 2008 CTP6 page compression--vary between 1.7 and 5.6. &lt;/P&gt;
&lt;P&gt;The space savings were substantial with these databases. When decompressed, the total space usage was ~261GB. Compared that to the total space usage of ~88GB when compressed. In other words, SQL Server 2008 page compression would save us 173GB in storage space.&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=SQL Server 2008 Page Compression: Compression ratios with real-world databases&amp;amp;body=Seen on SQLblog.com: %0A%0A%09SQL Server 2008 Page Compression: Compression ratios with real-world databases%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/05/11/sql-server-2008-page-compression-compression-ratios-from-real-world-databases.aspx" target="_blank" title = "Email SQL Server 2008 Page Compression: Compression ratios with real-world databases"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/11/sql-server-2008-page-compression-compression-ratios-from-real-world-databases.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Compression+ratios+with+real-world+databases" target="_blank" title = "Submit SQL Server 2008 Page Compression: Compression ratios with real-world databases to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/11/sql-server-2008-page-compression-compression-ratios-from-real-world-databases.aspx&amp;amp;phase=2" target="_blank" title = "Submit SQL Server 2008 Page Compression: Compression ratios with real-world databases to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/11/sql-server-2008-page-compression-compression-ratios-from-real-world-databases.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Compression+ratios+with+real-world+databases" target="_blank" title = "Submit SQL Server 2008 Page Compression: Compression ratios with real-world databases to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/11/sql-server-2008-page-compression-compression-ratios-from-real-world-databases.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Compression+ratios+with+real-world+databases" target="_blank" title = "Submit SQL Server 2008 Page Compression: Compression ratios with real-world databases to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/11/sql-server-2008-page-compression-compression-ratios-from-real-world-databases.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Compression+ratios+with+real-world+databases&amp;amp;;top=1" target="_blank" title = "Add SQL Server 2008 Page Compression: Compression ratios with real-world databases to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6750" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Storage" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Storage/default.aspx" /><category term="SQL Server 2008" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2008/default.aspx" /><category term="Data Compression" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Data+Compression/default.aspx" /></entry><entry><title>SQL Server 2008 Page Compression: Using multiple processors</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/05/05/sql-server-2008-page-compression-using-multiple-processors.aspx" /><link rel="enclosure" type="image/gif" length="6208" href="http://sqlblog.com/blogs/linchi_shea/attachment/6627.ashx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/05/05/sql-server-2008-page-compression-using-multiple-processors.aspx</id><published>2008-05-05T13:59:00Z</published><updated>2008-05-05T13:59:00Z</updated><content type="html">&lt;P&gt;SQL Server 2008 has introduced a long sought after feature -- Data Compression. This is a great feature, and I have no doubt it'll be widely used. The key compression method is called page compression, which uses the following three techniques to reduce the space taken up by duplicates on a page: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Row compression. This technique changes the storage formats of many fixed-length datatypes (e.g. char, int, money, binary, datetime, and so on) so that they occupy only the required number of bytes plus a small overhead.&lt;/LI&gt;
&lt;LI&gt;Prefix compression. This technique finds duplicate prefixes on a page for each column , and replaces each duplicate with a small reference number.&lt;/LI&gt;
&lt;LI&gt;Dictionary compression. This technique finds duplicate values on a page, collects them into a dictionary stored after the page header but before the data rows, and replaces the duplicate values with their corresponding offsets in the dictionary.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You can read more about SQL Server 2008 data compression in SQL2008 CTP6 Books Online. &lt;/P&gt;
&lt;P&gt;In this post, I'll focus on a very specific question: How does the number of processors impact rebuilding a table with page compression? Note that one way to enable page compression on a table is to rebuild it with the option data_compression set to page. The following is an example:&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#cccccc;"&gt;ALTER TABLE customer REBUILD WITH (DATA_COMPRESSION=PAGE);&lt;/DIV&gt;
&lt;P&gt;Since compressing a table is a CPU intensive operation, one naturally would expect that using multiple processors should help reduce the elapsed time of the above command. How do you instruct SQL Server 2008 to take advantage of multiple processors? There exists another rebuild option called MAXDOP, which you can use to inform SQL Server of the max number of processors you want the rebuild to use. The following is an example of setting the MAXDOP option to 8:&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#cccccc;"&gt;ALTER TABLE customer REBUILD WITH (DATA_COMPRESSION=PAGE, MAXDOP=8);&lt;/DIV&gt;
&lt;P&gt;To find out the impact of multiple processors (or the impact of setting MAXDOP to different values) on the elapsed time of the above command, I ran a series of tests with the command by setting MAXDOP to 0, 1, 2, 3, 4, 5, 6, 7, and 8 in turn. Before I report the test results, I should give you some information about the test setup:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The TPC-C customer table was used to produce all the test results reported here. However, the original customer table in the TPC-C benchmark was not very compressible because its data didn't include many duplicates. For test purposes, I 'cooked' the table to make it more compressible. After I cooked it, the data size of the table was ~2,181,864KB without data compression, and was ~439,672KB with page compression.&lt;/LI&gt;
&lt;LI&gt;The test server had 8 processors (with four dual-core sockets), and 8GB physical memory.&lt;/LI&gt;
&lt;LI&gt;The data point for each MAXDOP setting was collected with the following T-SQL script. While only MAXDOP = 2 is shown below, in the test, this script was repeated for each of the MAXDOP values 0 through 8.&lt;/LI&gt;&lt;/UL&gt;
&lt;DIV style="BACKGROUND-COLOR:#cccccc;"&gt;&lt;FONT face="Courier New"&gt;exec sp_spaceused 'customer';&lt;BR&gt;go&lt;BR&gt;DBCC DROPCLEANBUFFERS&lt;BR&gt;GO&lt;BR&gt;declare @dt datetime;&lt;BR&gt;select @dt = getdate();&lt;BR&gt;alter table customer rebuild with (data_compression=page, maxdop=2);&lt;BR&gt;select 'maxdop = 2', datediff(second, @dt, getdate());&lt;BR&gt;go&lt;BR&gt;exec sp_spaceused 'customer';&lt;BR&gt;go&lt;BR&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;P&gt;The following chart summarizes how the MAXDOP setting affects the elapsed time of rebuilding the customer table with page compression.&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/6627.ashx"&gt; &lt;/P&gt;
&lt;P&gt;A number of observations should be noted:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;SQL Server 2008 page compression can effectively take advantage of multiple processors to speed up rebuilding a table. Using more processors generally leads to shorter elapsed time.&lt;/LI&gt;
&lt;LI&gt;The diminishing return on the number of processors is clear from the chart. In this particular test environment, after 5 or 6 processors, adding another processor to rebuilding the table with page compression only reduced the elapsed time only marginally. The largest improvement was obtained when the number of processors was increased from one to two.&lt;/LI&gt;
&lt;LI&gt;When the MAXDOP option was set to 0, its effect was the same as when it's set to 8, which happened to be the total number of processors on the server.&lt;/LI&gt;
&lt;LI&gt;For this test setup, changing the buffer pool size from 6GB to 2GB did not materially alter the test results.&lt;/LI&gt;
&lt;LI&gt;With MAXDOP=8, all eight processors were seen to be used 100%--as reported by the perfmon counter Processor\% Processor Time--during the table rebuild.&lt;/LI&gt;&lt;/UL&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=SQL Server 2008 Page Compression: Using multiple processors&amp;amp;body=Seen on SQLblog.com: %0A%0A%09SQL Server 2008 Page Compression: Using multiple processors%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/05/05/sql-server-2008-page-compression-using-multiple-processors.aspx" target="_blank" title = "Email SQL Server 2008 Page Compression: Using multiple processors"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/05/sql-server-2008-page-compression-using-multiple-processors.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Using+multiple+processors" target="_blank" title = "Submit SQL Server 2008 Page Compression: Using multiple processors to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/05/sql-server-2008-page-compression-using-multiple-processors.aspx&amp;amp;phase=2" target="_blank" title = "Submit SQL Server 2008 Page Compression: Using multiple processors to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/05/sql-server-2008-page-compression-using-multiple-processors.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Using+multiple+processors" target="_blank" title = "Submit SQL Server 2008 Page Compression: Using multiple processors to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/05/sql-server-2008-page-compression-using-multiple-processors.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Using+multiple+processors" target="_blank" title = "Submit SQL Server 2008 Page Compression: Using multiple processors to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/05/05/sql-server-2008-page-compression-using-multiple-processors.aspx&amp;amp;title=SQL+Server+2008+Page+Compression%3a+Using+multiple+processors&amp;amp;;top=1" target="_blank" title = "Add SQL Server 2008 Page Compression: Using multiple processors to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6627" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Performance" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx" /><category term="SQL Server 2008" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/SQL+Server+2008/default.aspx" /><category term="Data Compression" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Data+Compression/default.aspx" /></entry><entry><title>Performance impact of controller cache: SQL Server read only workloads</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/04/01/performance-impact-of-controller-cache-sql-server-read-only-workloads.aspx" /><link rel="enclosure" type="image/gif" length="5836" href="http://sqlblog.com/blogs/linchi_shea/attachment/5944.ashx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/04/01/performance-impact-of-controller-cache-sql-server-read-only-workloads.aspx</id><published>2008-04-01T03:45:00Z</published><updated>2008-04-01T03:45:00Z</updated><content type="html">&lt;P class=MsoNormal&gt;In my &lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2008/03/29/performance-impact-of-controller-cache-sql-server-oltp-workloads.aspx"&gt;previous post&lt;/A&gt;, I looked at how a typical OLTP workload may be affected by various controller cache configurations. And the conclusion was that giving too much cache (say all 512MB) to reads hurt the OLTP performance. The primary reason was that the writes from the OLTP workloads were starved of cache. Now, let's take a look at how the controller cache configurations may impact on the performance of read queries whose execution plans are dominated by index seeks (both clustered and nonclustered). The TPC-C read-only transactions happen to be queries dominated by index seeks.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;As you'll see below, the index-seek dominated reads are not sensitive to controller cache configurations, at least for the test configurations described below.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The test configuration was exactly the same as what was described in the previous post except that the transaction mix was changed to the following to include only the two read-only transactions (i.e. Order Status and Stock Level). &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New"&gt;New Order:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0%&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New"&gt;Payment:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0%&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New"&gt;Order Status:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 50%&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New"&gt;Delivery:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0%&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New"&gt;Stock Level:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 50%&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=MsoNormal&gt;To measure the transaction throughput, I had to use a different metric because the New Order transaction was no longer executed in the tests. Instead, the transaction throughput was measured as the number of the Stock Level transaction executed per second. &lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Again, the three test scenarios differed only in how the controller cache was configured:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;0 MB was allocated to reads and 512MB was allocated to writes&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;128MB was allocated to reads and 384MB was allocated to writes&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;512MB was allocated to reads and 0 MB was allocated to writes&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=MsoNormal&gt;The test results are shown in the following chart:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/5944.ashx"&gt; &lt;/P&gt;
&lt;P class=MsoNormal&gt;The chart shows little difference in the transaction throughput among the three test scenarios. You could argue that the scenario where 128MB was allocated to read performed the best. But the transaction throughput difference was not significant enough to justify that conclusion, although the pattern was consistent throughout the repeated test runs, &lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;How was the I/O subsystem exercised by the read-only workloads? Let me again focus on the tests with 100 users. From a disk I/O perspective, the read-only workloads during the steady state can be characterized as follows:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;On the F drive with the data file, the key LoggicalDisk perfmon counter values were as follows:&lt;BR&gt;&lt;BR&gt;* Avg. Disk Bytes/Read = ~8366 bytes&lt;BR&gt;* Avg. Disk sec/Read = 0.347&lt;BR&gt;* Current Disk Queue Length = 122&lt;BR&gt;* Disk Reads/sec = 446&lt;BR&gt;&amp;nbsp;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;The key Buffer Manager counter values were as follows:&lt;BR&gt;&lt;BR&gt;* Page life expectancy = ~60&lt;BR&gt;* Page reads/sec = 478&lt;BR&gt;* Readahead pages/sec = 236&lt;BR&gt;* Target pages = 193176&lt;BR&gt;* Total pages = 193176&lt;BR&gt;&amp;nbsp;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;The Wait Statistics were heavily concentrated on Page IO latch waits.&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Performance impact of controller cache: SQL Server read only workloads&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Performance impact of controller cache: SQL Server read only workloads%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/04/01/performance-impact-of-controller-cache-sql-server-read-only-workloads.aspx" target="_blank" title = "Email Performance impact of controller cache: SQL Server read only workloads"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/04/01/performance-impact-of-controller-cache-sql-server-read-only-workloads.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+read+only+workloads" target="_blank" title = "Submit Performance impact of controller cache: SQL Server read only workloads to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/04/01/performance-impact-of-controller-cache-sql-server-read-only-workloads.aspx&amp;amp;phase=2" target="_blank" title = "Submit Performance impact of controller cache: SQL Server read only workloads to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/04/01/performance-impact-of-controller-cache-sql-server-read-only-workloads.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+read+only+workloads" target="_blank" title = "Submit Performance impact of controller cache: SQL Server read only workloads to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/04/01/performance-impact-of-controller-cache-sql-server-read-only-workloads.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+read+only+workloads" target="_blank" title = "Submit Performance impact of controller cache: SQL Server read only workloads to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/04/01/performance-impact-of-controller-cache-sql-server-read-only-workloads.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+read+only+workloads&amp;amp;;top=1" target="_blank" title = "Add Performance impact of controller cache: SQL Server read only workloads to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5944" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Performance" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx" /><category term="Testing" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Testing/default.aspx" /><category term="Storage" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Storage/default.aspx" /></entry><entry><title>Performance impact of controller cache: SQL Server OLTP workloads</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/03/29/performance-impact-of-controller-cache-sql-server-oltp-workloads.aspx" /><link rel="enclosure" type="image/gif" length="6078" href="http://sqlblog.com/blogs/linchi_shea/attachment/5900.ashx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/03/29/performance-impact-of-controller-cache-sql-server-oltp-workloads.aspx</id><published>2008-03-30T00:39:00Z</published><updated>2008-03-30T00:39:00Z</updated><content type="html">&lt;P class=MsoNormal&gt;Through empirical data presented in my two previous posts on the performance impact of controller cache configurations on &lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx"&gt;sequential disk I/O workloads&lt;/A&gt; and &lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2008/03/27/performance-impact-of-controller-cache-sql-server-large-operations.aspx"&gt;large SQL workloads&lt;/A&gt;, we observed that allocating controller cache to writes would result in better performance, at least with the described workloads. Let me now turn attention to SQL Server OLTP workloads, and check how the controller cache configurations may impact the transaction throughput of an archetypal OLTP workload--TPC-C in its standard transaction mix. &lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;As you'll see below, the same observation still holds.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The best way to understand TPC-C is to read its specifications at &lt;A href="http://www.tpc.org/"&gt;http://www.tpc.org/&lt;/A&gt;. But briefly, it models after the data processing of a business that sells items to customers in multiple districts. The customers may place orders for items, and the business maintains items in stock in multiple warehouses. The database keeps track of these business activities. So you'll find a customer table, an order table, an item table, a stock table, and so on. And like any real business, there are certain constraints among these tables so that you can't just scale one table without also scaling some other tables. In fact, the number of rows in most tables--thus the size of the database--is ultimately determined by the number of warehouses. So, if you want to test a larger database, you specify a larger number of warehouses. &lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;For my tests, I sized the test to 100 warehouses that resulted in about 9GB of allocated storage space. And to ensure that the disk I/Os would be heavily exercised, I set the SQL Server buffer pool to 2GB.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The data file was placed on the F drive and the log file was placed on the G drive. F and G were two individual 72GB 10,000rmp SAS disk drives that shared the same HP Smart Array P400 controller with 512MB for cache.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The stored procedures executed against these tables model five typical business activities: (1) placing a new order, (2) making a payment, (3) checking the order status, (4) making a delivery (i.e. fulfilling an order), and (5) checking the stock level. Among these stored procedures, order status and stock level are read only; the others are read/write. The transaction throughput metric is the number of new orders processed.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The standard transaction mix is as follows:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New"&gt;New Order:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 45%&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New"&gt;Payment:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;43%&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New"&gt;Order Status:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4%&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New"&gt;Delivery:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4%&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New"&gt;Stock Level:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4%&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;This simply means that, for instance, 45% of the time the client program submits the new order transaction (i.e. calling the new order stored procedure). Strictly speaking, what I ran can't be called TPC-C because not all the stringent TPC-C rules were followed. For instance, to simplify the tests, I did not leave any think time or wait time between consecutive database calls. But that works fine for this post since I just wanted to apply an OLTP workload to the test system and I'm not here to publish any official TPC-C results.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The test results are shown in the following chart:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/5900.ashx"&gt; 
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Note that what's important in this case is the relative throughputs among the three different test scenarios, and these three test scenarios were different only in how the controller cache was configured. The absolute throughput numbers do not mean anything.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;So as suspected, giving all 512MB of the controller cache to reads led to a significantly lower throughput, compared to the scenarios where a large portion of the cache (384MB or 512MB) was given to writes.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;How was the I/O subsystem exercised by these workloads? Let me focus on the tests with 100 users. From a disk I/O perspective, the OLTP workloads during the steady state can be characterized as follows:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;On the F drive with the data file&lt;BR&gt;&lt;/B&gt;I recorded the following perfmon counters:&lt;BR&gt;&lt;BR&gt;* Avg. Disk Bytes/Read = ~8KB, and Avg. Disk Bytes/Write = ~8KB&lt;BR&gt;* Avg. Disk sec/Read = ~275ms, and Avg. Disk sec/Write = ~320ms&lt;BR&gt;&lt;BR&gt;So 8KB pages were being read from the data file into the buffer pool randomly, and the lazy writer was writing 8KB pages out to the data file randomly. And these I/O requests saturated the F drive. Note that during the 3 minute test duration, one checkpoint was issued manually.&lt;BR&gt;&amp;nbsp;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;On the G drive with the log file&lt;BR&gt;&lt;/B&gt;I recorded the following perfmon counters:&lt;BR&gt;&lt;BR&gt;* Avg. Disk Bytes/Write = ~4KB&lt;BR&gt;* Avg. Disk sec/Write = ~28ms&lt;BR&gt;&lt;BR&gt;So SQL Server was writing to the log in ~4KB blocks, and the G drive was pushed hard.&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=MsoNormal&gt;If we look at the waitstats obtained during the test run, not surprisingly the waits were heavily concentrated on Page IO latch wait.&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Performance impact of controller cache: SQL Server OLTP workloads&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Performance impact of controller cache: SQL Server OLTP workloads%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/03/29/performance-impact-of-controller-cache-sql-server-oltp-workloads.aspx" target="_blank" title = "Email Performance impact of controller cache: SQL Server OLTP workloads"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/29/performance-impact-of-controller-cache-sql-server-oltp-workloads.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+OLTP+workloads" target="_blank" title = "Submit Performance impact of controller cache: SQL Server OLTP workloads to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/29/performance-impact-of-controller-cache-sql-server-oltp-workloads.aspx&amp;amp;phase=2" target="_blank" title = "Submit Performance impact of controller cache: SQL Server OLTP workloads to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/29/performance-impact-of-controller-cache-sql-server-oltp-workloads.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+OLTP+workloads" target="_blank" title = "Submit Performance impact of controller cache: SQL Server OLTP workloads to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/29/performance-impact-of-controller-cache-sql-server-oltp-workloads.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+OLTP+workloads" target="_blank" title = "Submit Performance impact of controller cache: SQL Server OLTP workloads to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/29/performance-impact-of-controller-cache-sql-server-oltp-workloads.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+OLTP+workloads&amp;amp;;top=1" target="_blank" title = "Add Performance impact of controller cache: SQL Server OLTP workloads to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5900" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author></entry><entry><title>Performance impact of controller cache: SQL Server large operations</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/03/27/performance-impact-of-controller-cache-sql-server-large-operations.aspx" /><link rel="enclosure" type="image/gif" length="19376" href="http://sqlblog.com/blogs/linchi_shea/attachment/5818.ashx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/03/27/performance-impact-of-controller-cache-sql-server-large-operations.aspx</id><published>2008-03-27T03:23:00Z</published><updated>2008-03-27T03:23:00Z</updated><content type="html">&lt;P class=MsoNormal&gt;In my previous post on &lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx"&gt;the performance impact of controller cache configurations&lt;/A&gt;, I presented some empirical results showing the performance impact of configuring the controller cache to various read/write settings on large sequential I/Os.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Why did I single out large sequential I/Os? That's because large sequential I/Os are heavily used by SQL Server in performing such critical operations as bulk loads, table scans, and checkpoints, to name a few. Since you are most likely a SQL Server professional, a natural question is: do the results in the previous post really translate into anything relevant to SQL Server performance? Conceptually, the answer is of course yes. &lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;But nothing beats seeing it directly. So I ran the following four SQL Server tests:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;Bulk Load&lt;/B&gt;&lt;BR&gt;A C# program was written to load data into the customer table using the System.Data.SqlClient.SqlBulkCopy class. The batch size for the bulk load was set to 50,000. The data was generated in the program per the TPC-C specifications for the customer table.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;Full table scan -- SELECT&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;After the clean buffer pages were dropped, the following query was run against the customer table: 
&lt;P class=MsoNormal&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT face="Courier New" size=2&gt;SELECT avg(c_balance) FROM customer;&lt;/FONT&gt; 
&lt;P class=MsoNormal&gt;Note that there is no index on the column c_balance.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;Full table scan -- UPDATE&lt;/B&gt; 
&lt;P class=MsoNormal&gt;After the clean buffer pages were dropped, the following update was run against the customer table: 
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp; UPDATE customer &lt;/FONT&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET c_data = 'a' + substring(c_data, 2, len(c_data))&lt;/FONT&gt; 
&lt;P class=MsoNormal&gt;There is no index on the c_data column.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;Checkpoint&lt;/B&gt;&lt;BR&gt;The 'recovery interval' sp_configure option was set to 32767 for the all tests mentioned in this post, effectively disabling automatic checkpoints. A manual checkpoint is issued after the UPDATE statement described above. This test measures the duration of that checkpoint. &lt;/P&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P class=MsoNormal&gt;All the tests were performed on the customer table in the TPC-C benchmark, whose DDL is included in the appendix. The customer table was populated with 3,000,000 rows, that took up about 2GB of storage space.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The tests were repeated multiple times for each of the following three test scenarios:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;0MB/512MB&lt;/B&gt;&lt;BR&gt;Out of the 512MB total cache in the disk controller, 0MB was allocated for reads and 512MB for writes.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;128MB/384MB&lt;/B&gt;&lt;BR&gt;Out of the 512MB total cache in the disk controller, 128MB was allocated for reads and 384MB for writes.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;512MB/0MB&lt;/B&gt;&lt;BR&gt;Out of the 512MB total cache in the disk controller, 512MB was allocated for reads and 0MB for writes.&lt;/P&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P class=MsoNormal&gt;The test results are shown in the following four charts.&lt;BR&gt;&amp;nbsp;&lt;/P&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/5818.ashx"&gt; 
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Figure 1 shows that for the bulk load benefited dramatically from controller write cache. When 512MB or 384MB was allocated to the write cache, the bulk load took about 53% of the time it took to load the same data when no write cache was allocated. From the perfmon, the bulk load was observed to cause ~64KB writes on both the data file and the log file of the test database.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Figure 2 shows that the full table scan query ran faster without any read cache in the controller. Per the perfmon counters, the table scan was doing &amp;gt;300KB reads.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Figure 3 shows that the full table scan update ran faster with write cache. Per the perfmon counters, the update was doing ~64KB writes to the log file. Figure 4 again shows that large sequential writes performed better with write cache because checkpoints were observed to be doing &amp;gt;128KB writes.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Overall, the results from these SQL Server operations are consistent with the results from pure I/Os tests described in the &lt;A href="http://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx"&gt;previous post&lt;/A&gt;.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;Appendix: DDL for the test table customer&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#cccccc;"&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;CREATE TABLE customer&lt;BR&gt;(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_id&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_d_id&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tinyint,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_w_id&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_first&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(16),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_middle&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(2),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_last&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(16),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_street_1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(20),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_street_2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(20),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_city&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(20),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_state&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(2),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_zip&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(9),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_phone&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(16),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_since&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; datetime,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_credit&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(2),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_credit_lim&amp;nbsp;&amp;nbsp; numeric(12,2),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_discount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numeric(4,4),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_balance&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numeric(12,2),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_ytd_payment&amp;nbsp; numeric(12,2),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_payment_cnt&amp;nbsp; smallint,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_delivery_cnt smallint,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c_data&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char(500)&lt;BR&gt;);&lt;BR&gt;go&lt;BR&gt;CREATE UNIQUE CLUSTERED INDEX ci_customer &lt;/FONT&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; on customer(c_w_id, c_d_id, c_id);&lt;BR&gt;CREATE UNIQUE NONCLUSTERED INDEX nc1_customer &lt;/FONT&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; on customer(c_w_id, c_d_id, c_last, c_first, c_id);&lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Performance impact of controller cache: SQL Server large operations&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Performance impact of controller cache: SQL Server large operations%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/03/27/performance-impact-of-controller-cache-sql-server-large-operations.aspx" target="_blank" title = "Email Performance impact of controller cache: SQL Server large operations"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/27/performance-impact-of-controller-cache-sql-server-large-operations.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+large+operations" target="_blank" title = "Submit Performance impact of controller cache: SQL Server large operations to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/27/performance-impact-of-controller-cache-sql-server-large-operations.aspx&amp;amp;phase=2" target="_blank" title = "Submit Performance impact of controller cache: SQL Server large operations to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/27/performance-impact-of-controller-cache-sql-server-large-operations.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+large+operations" target="_blank" title = "Submit Performance impact of controller cache: SQL Server large operations to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/27/performance-impact-of-controller-cache-sql-server-large-operations.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+large+operations" target="_blank" title = "Submit Performance impact of controller cache: SQL Server large operations to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/27/performance-impact-of-controller-cache-sql-server-large-operations.aspx&amp;amp;title=Performance+impact+of+controller+cache%3a+SQL+Server+large+operations&amp;amp;;top=1" target="_blank" title = "Add Performance impact of controller cache: SQL Server large operations to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5818" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Performance" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx" /><category term="Testing" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Testing/default.aspx" /><category term="Storage" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Storage/default.aspx" /></entry><entry><title>Performance impact of controller read cache: large sequential I/Os</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx" /><link rel="enclosure" type="image/gif" length="13128" href="http://sqlblog.com/blogs/linchi_shea/attachment/5763.ashx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx</id><published>2008-03-24T16:14:00Z</published><updated>2008-03-24T16:14:00Z</updated><content type="html">&lt;P class=MsoNormal&gt;In the next several blog posts, I’ll share with you some empirical results concerning the performance impact of configuring the read/write cache of a disk controller.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;In the comments on Joe Chang’s blog at this site on &lt;A href="http://sqlblog.com/blogs/joe_chang/archive/2008/03/04/storage-performance-for-sql-server.aspx"&gt;Storage Performance for SQL Server&lt;/A&gt;, some statements were made concerning the performance impact of read cache in a disk controller. Joe and I agreed that read cache doesn’t really help for&amp;nbsp;what matters. In fact, it may degrade the performance of large sequential reads. In this blog post, I’ll give you some supporting evidence. &lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;All the data points reported in this blog post were obtained on an HP Smart Array P400 SAS controller with 512MB of cache that could be configured for either reads or writes, or a combination of reads and writes. There were three 72GB 10,000rpm SAS drives hanging off the controller, and they were configured as three separate disks (i.e. just a bunch of disks). &lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The results reported in this and the next few blog posts were from tests done on a 10GB test file on one of the three disks. The test tool was conducted primarily with sqlio.exe, and the I/O commands executed are listed at the end of this post.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The two charts below illustrate the performance impact of various cache settings on the throughput of 256KB sequential reads and that of 256KB sequential writes at various I/O load levels. The top chart is for 256KB sequential reads and the bottom chart is for 256KB sequential writes. Note that each data point in the charts represents the consistent results from many repeated test runs in the configured test environment.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;IMG src="http://sqlblog.com/blogs/linchi_shea/attachment/5763.ashx"&gt; &lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;As is evident in the top chart, the throughput of 256KB sequential reads can be degraded by the presence of a significant amount of read cache. In this case, 256KB sequential reads actually experienced a rather large drop in throughput (~20%) from ~73MB per second when no read cache was allocated to ~53MB per second when 512MB was allocated to reads. &lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The bottom chart suggests that increasing the amount of controller cache for writes did improve the performance of 256KB sequential writes. When the write cache was increased from 0MB to 512MB, the throughput of 256KB sequential writes went up from 57MB per second to 62MB per second, an increase of ~9%. &lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Now does this mean that the controller cache should be all allocate to writes? I’ll address that question in the next several posts in the context of other I/O workloads. But let me give you a hint before I get to the next post. Note that in the top chart there was no performance difference in 256KB sequential reads whether 0MB or 128MB was allocated to the read cache. Also note that in the bottom chart there was no performance difference in 256KB sequential writes whether 512MB or 384MB was allocated to the write cache. This is significant as other read I/O workloads may benefit from a small amount of read cache without harming the write I/O workloads.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;Appendix: Batch file for large sequential I/Os&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;call sqlIO.exe -kW -s30 -o2&amp;nbsp;&amp;nbsp; -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kW -s30 -o8&amp;nbsp;&amp;nbsp; -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kW -s30 -o16&amp;nbsp; -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kW -s30 -o32&amp;nbsp; -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kW -s30 -o64&amp;nbsp; -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kW -s30 -o128 -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kW -s30 -o256 -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;&lt;BR&gt;call sqlIO.exe -kR -s30 -o2&amp;nbsp;&amp;nbsp; -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kR -s30 -o8&amp;nbsp;&amp;nbsp; -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kR -s30 -o16&amp;nbsp; -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kR -s30 -o32&amp;nbsp; -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kR -s30 -o64&amp;nbsp; -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kR -s30 -o128 -fsequential -b256 -BH -LS -Fparam_F.txt&lt;BR&gt;call sqlIO.exe -kR -s30 -o256 -fsequential -b256 -BH -LS -Fparam_F.txt&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;where the content of the parameter file &lt;FONT face=Courier&gt;param_F.txt&lt;/FONT&gt; is as follows:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;F:\testfile.dat 1 0x0 10000&lt;/FONT&gt;&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Performance impact of controller read cache: large sequential I/Os&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Performance impact of controller read cache: large sequential I/Os%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx" target="_blank" title = "Email Performance impact of controller read cache: large sequential I/Os"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx&amp;amp;title=Performance+impact+of+controller+read+cache%3a+large+sequential+I%2fOs" target="_blank" title = "Submit Performance impact of controller read cache: large sequential I/Os to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx&amp;amp;phase=2" target="_blank" title = "Submit Performance impact of controller read cache: large sequential I/Os to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx&amp;amp;title=Performance+impact+of+controller+read+cache%3a+large+sequential+I%2fOs" target="_blank" title = "Submit Performance impact of controller read cache: large sequential I/Os to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx&amp;amp;title=Performance+impact+of+controller+read+cache%3a+large+sequential+I%2fOs" target="_blank" title = "Submit Performance impact of controller read cache: large sequential I/Os to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/24/performance-impact-of-controller-read-cache-large-sequential-i-os.aspx&amp;amp;title=Performance+impact+of+controller+read+cache%3a+large+sequential+I%2fOs&amp;amp;;top=1" target="_blank" title = "Add Performance impact of controller read cache: large sequential I/Os to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5763" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Performance" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx" /><category term="Testing" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Testing/default.aspx" /><category term="Storage" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Storage/default.aspx" /></entry><entry><title>Is the 8KB page obsolete or aging?</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/03/03/is-the-8kb-page-obsolete-or-aging.aspx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/03/03/is-the-8kb-page-obsolete-or-aging.aspx</id><published>2008-03-04T00:07:00Z</published><updated>2008-03-04T00:07:00Z</updated><content type="html">&amp;nbsp; 
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;In one of their year 2000 papers—&lt;/FONT&gt;&lt;A href="http://research.microsoft.com/~gray/papers/MS_TR_99_100_Rules_of_Thumb_in_Data_Engineering.pdf"&gt;&lt;FONT face="Times New Roman" size=3&gt;Rules of Thumb in Data Engineering&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Times New Roman" size=3&gt;, Jim Gray and Prashant Shenoy stated that, “Over the last decade, disk pages have grown from 2KB to 8KB and poised to grow again. In ten years, the typical &lt;I style="mso-bidi-font-style:normal;"&gt;small&lt;/I&gt; transfer unit will probably be 64KB, and large transfer units will be a megabyte or more.”&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;Should we expect the page size of SQL Server to grow? Or is the 8KB page size still optimal for SQL Server? &lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;I remember discussing this very question with someone in the know about a year ago, and was told that the suggestion of using a larger page size in SQL Server was more BS than substance. The argument was essentially that SQL Server rarely incurs 8KB I/Os, and it always tries to ‘batch up’ I/Os into large transfers when it does such operations as read-ahead reads, checkpoints, lazy writes, and so on.&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’m not here to argue for or against using a single fixed 8KB page size in SQL Server. I’m simply not in a position to do justice to the topic. I’m sure Microsoft has been experimenting with different page sizes. At least, I sure hope so.&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 just want to highlight some observations related to this topic.&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;First, note that SQL Server’s choice of a single fixed 8KB page is different from Oracle and DB2, which allow multiple page/block sizes. A single fixed page size can obviously lead to simplified code, but at the same time has the potential to introduce this fixed page size assumption throughout the code, making it difficult to accommodate a different page size should that becomes necessary.&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;Although the fact that it uses 8KB pages doesn’t necessarily mean that SQL Server would perform a lot of 8KB I/Os, it is not that rare to see SQL Server does 8KB I/Os in real world applications. This is especially true when there is fragmentation within a database.&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;Conceptually, it does seem that the larger the page size, the more row slots you can have on a page, and therefore fewer levels you may have for your indexes. Potentially, this can lead to fewer page splits and fewer physical I/Os. On the flip side, a larger page size may have a higher chance for running into unwanted concurrency issues, though this shouldn’t really be a problem with row-level locking. The other argument against a large page size is that if your workload typically requests a small chunk of data, getting a 32KB or even 64KB page into the buffer pool only to use a few short rows could be wasteful.&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 introduction of database compression in SQL Server 2008—its dictionary compression in particular—seems to give some legitimacy to the question of whether the 8KB page starts to show signs of aging. For instance, with dictionary compression, it may work better with larger pages. Intuitively, the larger the page size, the more likely you may see repeating data patterns and the less overhead space the compression information structure may take. Oracle uses a similar block-level compression scheme and research and experience on the Oracle compression has shown that generally larger blocks tend to produce better compression ratios.&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;Now if you check the Oracle literature, you would find some rather heated debate on whether there is any value in using multiple block sizes in a real world app. Most agree that using a larger block size in data warehousing applications tend to result in better performance. But some have argued that the performance gain may not be worth the added hassle in managing multiple block sizes, and people may be better off just staying with the default block size, which happens to be 8KB.&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;So this is not a settled topic. It remains interesting to see whether Microsoft will change the page size or introduce multiple page sizes post SQL Server 2008.&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;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Is the 8KB page obsolete or aging?&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Is the 8KB page obsolete or aging?%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/03/03/is-the-8kb-page-obsolete-or-aging.aspx" target="_blank" title = "Email Is the 8KB page obsolete or aging?"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/03/is-the-8kb-page-obsolete-or-aging.aspx&amp;amp;title=Is+the+8KB+page+obsolete+or+aging%3f" target="_blank" title = "Submit Is the 8KB page obsolete or aging? to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/03/is-the-8kb-page-obsolete-or-aging.aspx&amp;amp;phase=2" target="_blank" title = "Submit Is the 8KB page obsolete or aging? to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/03/is-the-8kb-page-obsolete-or-aging.aspx&amp;amp;title=Is+the+8KB+page+obsolete+or+aging%3f" target="_blank" title = "Submit Is the 8KB page obsolete or aging? to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/03/is-the-8kb-page-obsolete-or-aging.aspx&amp;amp;title=Is+the+8KB+page+obsolete+or+aging%3f" target="_blank" title = "Submit Is the 8KB page obsolete or aging? to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/03/03/is-the-8kb-page-obsolete-or-aging.aspx&amp;amp;title=Is+the+8KB+page+obsolete+or+aging%3f&amp;amp;;top=1" target="_blank" title = "Add Is the 8KB page obsolete or aging? to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5426" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Architecture" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Architecture/default.aspx" /><category term="General trends" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/General+trends/default.aspx" /></entry><entry><title>Drive letters should go</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/02/29/drive-letters-should-go.aspx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/02/29/drive-letters-should-go.aspx</id><published>2008-02-29T21:27:00Z</published><updated>2008-02-29T21:27:00Z</updated><content type="html">&lt;P class=MsoNormal style="MARGIN:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Recently, I was involved in designing a SQL2005 cluster. Let’s just say that it was going to have many more nodes until we found that we had to scale down to a 3+1 cluster because of drive letter limitation. The annoying thing is that even with a 3+1 cluster and with mountpoints used to the limit, we may still run out of drive letters. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;With each node being a four-socket quad-core server, this 3+1 cluster would have 64 cores in total. Not a huge deal these days, but still quite a bit computing power nevertheless! &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Since this a database consolidation environment, we want to be able to accommodate as many databases in a SQL instance as we practically and sanely can. That means fewer instances, and possibly better resource utilization. On the other hand, we want to be able to contain and fence the resource utilization of each application whose databases are hosted in this cluster. That means isolating their databases into their own SQL2005 instances and fencing the corresponding Windows processes with processor affinity and/or some kind of Windows resource management utility.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;It’s common that many applications don’t need the computing power of all 16 cores. In fact, many applications may not even need two cores. But let’s assume that for capacity planning purposes, we’ll offer two cores as the minimum unit for a SQL2005 instance. So we can support up to 16 / 2 = 8 instances on each node. In this cluster with three node active, we can accommodate 3 x 8 = 24 instances. But wait! Each SQL2005 instance needs at least one drive letter, and the letter C is already taken. So we can’t really support 24 SQL2005 instances. In many environments, two or three drive letters are often reserved on each server, therefore, the practical number of available drive letters is probably 20 or less.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Now, in reality, to be serious, how often do you really want that many SQL2005 instances in a cluster? Probably not very often at all. But as computing power increases, it’ll increasingly become more likely. In fact, we were considering a 6+2 cluster before we realized that we probably didn’t want to go there because of the drive letter limit. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Is it insane to have this many instances in a cluster? If that’s the case, why does Microsoft continues to bump up the number nodes in a cluster? Even if the number of your instances in a cluster is well below the upper limit, you don’t want to later run into a situation where you have to migrate your instances somewhere else just to avoid running out of drive letters. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;From a strictly system design perspective, drive letters are completely archaic and not cool. The restriction is artificial and a product of a primitive era. Okay, I don’t want to over do it here as what is cool to me may not be cool to you!&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The strongest argument, however, is competition. When they can easily do 6+2 failover clusters, for SQL Server to be limited by drive letters, it is just an unnecessary distraction we can do without.&lt;/FONT&gt;&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Drive letters should go&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Drive letters should go%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/02/29/drive-letters-should-go.aspx" target="_blank" title = "Email Drive letters should go"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/29/drive-letters-should-go.aspx&amp;amp;title=Drive+letters+should+go" target="_blank" title = "Submit Drive letters should go to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/29/drive-letters-should-go.aspx&amp;amp;phase=2" target="_blank" title = "Submit Drive letters should go to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/29/drive-letters-should-go.aspx&amp;amp;title=Drive+letters+should+go" target="_blank" title = "Submit Drive letters should go to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/29/drive-letters-should-go.aspx&amp;amp;title=Drive+letters+should+go" target="_blank" title = "Submit Drive letters should go to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/29/drive-letters-should-go.aspx&amp;amp;title=Drive+letters+should+go&amp;amp;;top=1" target="_blank" title = "Add Drive letters should go to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5373" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Storage" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Storage/default.aspx" /><category term="Rant" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Rant/default.aspx" /><category term="General trends" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/General+trends/default.aspx" /></entry><entry><title>Hexa-core and query parallelism</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/02/28/hexa-core-and-query-parallelism.aspx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/02/28/hexa-core-and-query-parallelism.aspx</id><published>2008-02-28T17:03:00Z</published><updated>2008-02-28T17:03:00Z</updated><content type="html">&lt;P class=MsoNormal style="MARGIN:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;I was struck by two things yesterday. One was that internet—the blogsphere in particular—was abuzz over the leaked information on Intel Dunnington chip, which is a six-core processor that is socket-compatible with Intel Tigerton (i.e. Xeon 7300). Do a Google search on the keywords: Intel Dunnington, and you’ll find plenty of information.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The other thing was that I got involved with a client in yet another round of discussions concerning query parallelism, which was prompted by a Microsoft support’s recommendation to turn off query parallelism for some batch processing because of certain problems with parallelism.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Intel as well as AMD is clearly on the march along their roadmap towards multi-core and many-core chips. And that is putting a lot of pressure on the software development community to ensure that their software can take full advantage of this rapid increase in computing power. The pace of hardware progress is outstripping that of software development. Among all the software applications, DBMS including SQL Server are relatively better positioned to keep pace with this multi-core/many-core march because they are inherently multi-threaded (or multi-tasked).&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;That said, programming parallelism is not trivial, and programming scalable parallelism is hard. If you have worked with SQL Server query parallelism in its current state, you know it doesn’t always do exactly what you want. With multi cores/many cores becoming a norm, you won’t afford to just turn it off when there is a problem here or there, as it is currently a ‘generally accepted’ practice. Query parallelism needs to become a lot more robust. And since it’s just not realistic to be completely problem free, query parallelism also needs to become a lot more granular so that the problem can be localized and if it comes to it, query parallelism can be turned on or off in isolated area.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: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:0pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The six-core Dunnington processor will be released second half of this year. That corresponds more or less with the release of SQL Server 2008. Note that four-socket servers are common. With Dunnington, that gives us 24 cores on a commodity server. And there are also some eight-socket x64 servers, though less common. And that would give us 48 cores on a commodity server. It’ll be interesting to see how SQL Server 2008&amp;nbsp;scales on&amp;nbsp;these 24-core or 48-core x64 commodity servers.&lt;/FONT&gt;&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Hexa-core and query parallelism&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Hexa-core and query parallelism%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/02/28/hexa-core-and-query-parallelism.aspx" target="_blank" title = "Email Hexa-core and query parallelism"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/28/hexa-core-and-query-parallelism.aspx&amp;amp;title=Hexa-core+and+query+parallelism" target="_blank" title = "Submit Hexa-core and query parallelism to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/28/hexa-core-and-query-parallelism.aspx&amp;amp;phase=2" target="_blank" title = "Submit Hexa-core and query parallelism to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/28/hexa-core-and-query-parallelism.aspx&amp;amp;title=Hexa-core+and+query+parallelism" target="_blank" title = "Submit Hexa-core and query parallelism to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/28/hexa-core-and-query-parallelism.aspx&amp;amp;title=Hexa-core+and+query+parallelism" target="_blank" title = "Submit Hexa-core and query parallelism to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/28/hexa-core-and-query-parallelism.aspx&amp;amp;title=Hexa-core+and+query+parallelism&amp;amp;;top=1" target="_blank" title = "Add Hexa-core and query parallelism to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5338" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Hardware platforms" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Hardware+platforms/default.aspx" /><category term="General trends" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/General+trends/default.aspx" /></entry><entry><title>You Gotta Stop Writing Tautologies</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/02/21/you-gotta-stop-writing-tautologies.aspx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/02/21/you-gotta-stop-writing-tautologies.aspx</id><published>2008-02-21T22:44:00Z</published><updated>2008-02-21T22:44:00Z</updated><content type="html">&lt;P&gt;Windows performance monitor is an excellent tool. But the online explanations for many perfmon counters often drive me nuts. &lt;/P&gt;
&lt;P&gt;Take the counter "SQLServer:Databases\Log Growths" as an example. Its explain text is "Total number of log growths for this database." Well, that doesn't really add much to the information already conveyed by the counter name, does it? If the writer could just add one or two more sentences, it&amp;nbsp;would make the explain text much more useful. Say,&amp;nbsp;add a sentence to explicitly identify whether this includes both manual growths and autogrowths.&lt;/P&gt;
&lt;P&gt;As another example, the explain text for the counter "SQLServer:General Statistics\Logical Connections" says "Number of logical connections to the system." Great! That's really helpful! How about adding a quick sentence to explain what is a logical connnection?&lt;/P&gt;
&lt;P&gt;I understand there is very limited space for the explain text. But it does have enough space for a few more short sentences. &lt;/P&gt;
&lt;P&gt;It's a total waste of time to provide this type of useless repetitions.&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=You Gotta Stop Writing Tautologies&amp;amp;body=Seen on SQLblog.com: %0A%0A%09You Gotta Stop Writing Tautologies%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/02/21/you-gotta-stop-writing-tautologies.aspx" target="_blank" title = "Email You Gotta Stop Writing Tautologies"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/21/you-gotta-stop-writing-tautologies.aspx&amp;amp;title=You+Gotta+Stop+Writing+Tautologies" target="_blank" title = "Submit You Gotta Stop Writing Tautologies to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/21/you-gotta-stop-writing-tautologies.aspx&amp;amp;phase=2" target="_blank" title = "Submit You Gotta Stop Writing Tautologies to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/21/you-gotta-stop-writing-tautologies.aspx&amp;amp;title=You+Gotta+Stop+Writing+Tautologies" target="_blank" title = "Submit You Gotta Stop Writing Tautologies to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/21/you-gotta-stop-writing-tautologies.aspx&amp;amp;title=You+Gotta+Stop+Writing+Tautologies" target="_blank" title = "Submit You Gotta Stop Writing Tautologies to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/21/you-gotta-stop-writing-tautologies.aspx&amp;amp;title=You+Gotta+Stop+Writing+Tautologies&amp;amp;;top=1" target="_blank" title = "Add You Gotta Stop Writing Tautologies to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5191" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Rant" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Rant/default.aspx" /></entry><entry><title>The End of an Architectural Era?</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/02/20/the-end-of-an-architectural-era.aspx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/02/20/the-end-of-an-architectural-era.aspx</id><published>2008-02-20T15:49:00Z</published><updated>2008-02-20T15:49:00Z</updated><content type="html">&lt;P&gt;Alan Cranfield on the SSWUG list alerted me to a paper by Mike Stonebraker and folks, proclaiming the end of the current relational database architecture that is generally embraced by all the major commercial relational DBMS and annoucing that a far better paradigm would be based on specialized engines. You can find the paper here:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.vldb.org/conf/2007/papers/industrial/p1150-stonebraker.pdf"&gt;http://www.vldb.org/conf/2007/papers/industrial/p1150-stonebraker.pdf&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;If anybody can make this type of bold prediction, Stonebraker certainly can, given that he is a pioneer and authority of the relational DBMS and such a fixture in the relational DBMS filed.&amp;nbsp;That of course doesn't necessarily give him exclusive&amp;nbsp;ownership to predicting the future. But whether or not you believe Mike Stonebraker has the crystal ball into the&amp;nbsp;DBMS furture, the paper is an interesting read from a general DBMS architectural perspective.&lt;/P&gt;
&lt;P&gt;To some extent, one can argue that DB2 v9 is moving in the direction of specialized engines when it has two separate engines, one relational and the other XML, in one system, albeit as a commercial system DB2 is nowhere near the radical proposal Stonebraker is advocating.&lt;/P&gt;
&lt;P&gt;Now when it comes to this blog site, the Stonebraker paper is relevant to the discussions regarding 'beyond relational'. To some, this would be adding salt to the wound :-) For those who would like to continue that thread of discussions, take a look at &lt;A href="http://www.dbms2.com/2008/02/15/non-relational-database-management/"&gt;http://www.dbms2.com/2008/02/15/non-relational-database-management/&lt;/A&gt;.&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=The End of an Architectural Era?&amp;amp;body=Seen on SQLblog.com: %0A%0A%09The End of an Architectural Era?%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/02/20/the-end-of-an-architectural-era.aspx" target="_blank" title = "Email The End of an Architectural Era?"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/20/the-end-of-an-architectural-era.aspx&amp;amp;title=The+End+of+an+Architectural+Era%3f" target="_blank" title = "Submit The End of an Architectural Era? to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/20/the-end-of-an-architectural-era.aspx&amp;amp;phase=2" target="_blank" title = "Submit The End of an Architectural Era? to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/20/the-end-of-an-architectural-era.aspx&amp;amp;title=The+End+of+an+Architectural+Era%3f" target="_blank" title = "Submit The End of an Architectural Era? to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/20/the-end-of-an-architectural-era.aspx&amp;amp;title=The+End+of+an+Architectural+Era%3f" target="_blank" title = "Submit The End of an Architectural Era? to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/20/the-end-of-an-architectural-era.aspx&amp;amp;title=The+End+of+an+Architectural+Era%3f&amp;amp;;top=1" target="_blank" title = "Add The End of an Architectural Era? to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5171" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Architecture" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Architecture/default.aspx" /></entry><entry><title>Microsoft 2008 Winter Scripting Games</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/02/19/microsoft-2008-winter-scripting-games.aspx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/02/19/microsoft-2008-winter-scripting-games.aspx</id><published>2008-02-19T16:40:00Z</published><updated>2008-02-19T16:40:00Z</updated><content type="html">Microsoft is running its 3rd annual Winter Scripting Games. Three languages are allowed: VBScript, PowerShell, and Perl. The event sounds interesting. Check it out at:&lt;FONT size=2&gt; 
&lt;P&gt;&lt;/FONT&gt;&lt;A href="http://www.microsoft.com/technet/scriptcenter/funzone/games/default.mspx"&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;http://www.microsoft.com/technet/scriptcenter/funzone/games/default.mspx&lt;/U&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;I didn't know about&amp;nbsp;this event&amp;nbsp;until somebody emailed me this morning. You bet I'll be looking into it, if not for anything else but to find whether there are compelling reasons for PowerShell :-)&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Microsoft 2008 Winter Scripting Games&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Microsoft 2008 Winter Scripting Games%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/02/19/microsoft-2008-winter-scripting-games.aspx" target="_blank" title = "Email Microsoft 2008 Winter Scripting Games"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/19/microsoft-2008-winter-scripting-games.aspx&amp;amp;title=Microsoft+2008+Winter+Scripting+Games" target="_blank" title = "Submit Microsoft 2008 Winter Scripting Games to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/19/microsoft-2008-winter-scripting-games.aspx&amp;amp;phase=2" target="_blank" title = "Submit Microsoft 2008 Winter Scripting Games to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/19/microsoft-2008-winter-scripting-games.aspx&amp;amp;title=Microsoft+2008+Winter+Scripting+Games" target="_blank" title = "Submit Microsoft 2008 Winter Scripting Games to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/19/microsoft-2008-winter-scripting-games.aspx&amp;amp;title=Microsoft+2008+Winter+Scripting+Games" target="_blank" title = "Submit Microsoft 2008 Winter Scripting Games to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/19/microsoft-2008-winter-scripting-games.aspx&amp;amp;title=Microsoft+2008+Winter+Scripting+Games&amp;amp;;top=1" target="_blank" title = "Add Microsoft 2008 Winter Scripting Games to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5139" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Scripting" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Scripting/default.aspx" /></entry><entry><title>Amdahl’s Law</title><link rel="alternate" type="text/html" href="http://sqlblog.com/blogs/linchi_shea/archive/2008/02/12/amdahl-s-law.aspx" /><id>http://sqlblog.com/blogs/linchi_shea/archive/2008/02/12/amdahl-s-law.aspx</id><published>2008-02-12T04:43:00Z</published><updated>2008-02-12T04:43:00Z</updated><content type="html">&lt;P class=MsoNormal&gt;For the past few weeks, I’ve been working on a diverse array of issues ranging from studying SQL Server performance on various multi-core processors, pondering the implications of many-core processors, troubleshooting SQL Server performance problems, looking at the scalability of Oracle RAC and Sybase shared-disk clusters, and so on.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Everywhere I turned, I bumped into the signs of Amdahl’s law, in particular Amdahl’s parallelism law. If you studied the computer architecture in school, you almost certainly have come across Amdahl’s various laws including his parallelism law below:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT:0.25in;"&gt;&lt;I&gt;If a computation has a serial component S, a parallel component P, and there are N processors, then the maximum speedup is as follows&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;
&lt;TABLE class=MsoTableGrid style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;MARGIN-LEFT:23.4pt;BORDER-COLLAPSE:collapse;BORDER-RIGHT-WIDTH:0px;" cellSpacing=0 cellPadding=0 class="MsoTableGrid"&gt;

&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT:medium none;PADDING-RIGHT:5.4pt;BORDER-TOP:medium none;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0in;BORDER-LEFT:medium none;WIDTH:80px;PADDING-TOP:0in;BORDER-BOTTOM:medium none;" rowSpan=2&gt;
&lt;P class=MsoNormal&gt;&lt;I&gt;Speedup =&lt;/I&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" style="BORDER-RIGHT:medium none;PADDING-RIGHT:5.4pt;BORDER-TOP:medium none;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0in;BORDER-LEFT:medium none;WIDTH:136px;PADDING-TOP:0in;BORDER-BOTTOM:windowtext;"&gt;
&lt;P class=MsoNormal style="TEXT-ALIGN:center;" align=center&gt;&lt;I&gt;S + P&lt;/I&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT:medium none;PADDING-RIGHT:5.4pt;BORDER-TOP:medium none;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0in;BORDER-LEFT:medium none;WIDTH:136px;PADDING-TOP:0in;BORDER-BOTTOM:medium none;"&gt;
&lt;DIV style="BORDER-TOP:1px solid;PADDING-TOP:1px;"&gt;
&lt;P class=MsoNormal style="TEXT-ALIGN:center;" align=center&gt;&lt;I&gt;S + P / N&lt;/I&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;&lt;I&gt;&lt;/I&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;This law is often stated in various alternative but equivalent forms. The following is an alternative expression of Amdahl’s law in terms of the fraction of the computation that must be done serially (F):&lt;/P&gt;
&lt;P&gt;
&lt;TABLE class=MsoTableGrid style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;MARGIN-LEFT:23.4pt;BORDER-COLLAPSE:collapse;BORDER-RIGHT-WIDTH:0px;" cellSpacing=0 cellPadding=0 class="MsoTableGrid"&gt;

&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT:medium none;PADDING-RIGHT:5.4pt;BORDER-TOP:medium none;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0in;BORDER-LEFT:medium none;WIDTH:79px;PADDING-TOP:0in;BORDER-BOTTOM:medium none;" rowSpan=2&gt;
&lt;P class=MsoNormal&gt;&lt;I&gt;Speedup =&lt;/I&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" style="BORDER-RIGHT:medium none;PADDING-RIGHT:5.4pt;BORDER-TOP:medium none;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0in;BORDER-LEFT:medium none;WIDTH:137px;PADDING-TOP:0in;BORDER-BOTTOM:windowtext;"&gt;
&lt;P class=MsoNormal style="TEXT-ALIGN:center;" align=center&gt;&lt;I&gt;1&lt;/I&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT:medium none;PADDING-RIGHT:5.4pt;BORDER-TOP:medium none;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0in;BORDER-LEFT:medium none;WIDTH:137px;PADDING-TOP:0in;BORDER-BOTTOM:medium none;"&gt;
&lt;DIV style="BORDER-TOP:1px solid;PADDING-TOP:1px;"&gt;
&lt;P class=MsoNormal style="TEXT-ALIGN:center;" align=center&gt;&lt;I&gt;F + (1 – F)&amp;nbsp; /&amp;nbsp; N&lt;/I&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;One of many important implications of this law is that even if the number of processors goes to infinity, the maximum speedup you may get is:&lt;/P&gt;
&lt;P&gt;
&lt;TABLE class=MsoTableGrid style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;MARGIN-LEFT:23.4pt;BORDER-COLLAPSE:collapse;BORDER-RIGHT-WIDTH:0px;" cellSpacing=0 cellPadding=0 class="MsoTableGrid"&gt;

&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT:medium none;PADDING-RIGHT:5.4pt;BORDER-TOP:medium none;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0in;BORDER-LEFT:medium none;WIDTH:106px;PADDING-TOP:0in;BORDER-BOTTOM:medium none;" rowSpan=2&gt;
&lt;P class=MsoNormal&gt;&lt;I&gt;Max Speedup =&lt;/I&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" style="BORDER-RIGHT:medium none;PADDING-RIGHT:5.4pt;BORDER-TOP:medium none;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0in;BORDER-LEFT:medium none;WIDTH:113px;PADDING-TOP:0in;BORDER-BOTTOM:windowtext;"&gt;
&lt;P class=MsoNormal style="TEXT-ALIGN:center;" align=center&gt;&lt;I&gt;S + P&lt;/I&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT:medium none;PADDING-RIGHT:5.4pt;BORDER-TOP:medium none;PADDING-LEFT:5.4pt;PADDING-BOTTOM:0in;BORDER-LEFT:medium none;WIDTH:113px;PADDING-TOP:0in;BORDER-BOTTOM:medium none;"&gt;
&lt;DIV style="BORDER-TOP:1px solid;PADDING-TOP:1px;"&gt;
&lt;P class=MsoNormal style="TEXT-ALIGN:center;" align=center&gt;&lt;I&gt;S&lt;/I&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Therefore, if the serial component is a large fraction of the whole computation, you won’t get much speedup no matter how many processors you may have. On the other hand, if the parallel component is large, the speedup can be significant.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;So, if your system has a shared global state, for consistency it must be accessed (updated) in a serialized fashion. This law suggests that if your workload is seriously bottlenecked on this global state, you won’t get much performance improvement by focusing your efforts on getting better processors, more processors, or improving any other hardware or software parallel components.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;In the case of using the Intel multi-core processors, if your workload happens to bottleneck on its front-side bus, it most likely would not help to switch to faster processors. For an interesting discussion of the implications of Amdahl's law on multicore computing, I highly recommend reading this article: "&lt;A href="http://www.cs.wisc.edu/multifacet/papers/tr1593_amdahl_multicore.pdf"&gt;Amdahl's Law in the Multicore Era&lt;/A&gt;".&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;And if you are designing a database application, but the design relies heavily on the shared tempdb, thus causing significant serialization on the tempdb system data structures, the scalability of your app will suffer.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;In the case of RAC and Sybase shared-disk clusters, if your workload is such that it cause a huge amount of inter-node traffic to maintain cache coherency, your app will not scale well with more nodes in the cluster.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;These observations are intuitive, and are easy to understand without you ever being exposed to Amdahl’s law. However, Amdahl’s law elegantly highlights the common thread to you, and is worth revisiting from time to time.&lt;/P&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Amdahl’s Law&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Amdahl’s Law%0A%0Ahttp://sqlblog.com/blogs/linchi_shea/archive/2008/02/12/amdahl-s-law.aspx" target="_blank" title = "Email Amdahl’s Law"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/12/amdahl-s-law.aspx&amp;amp;title=Amdahl%e2%80%99s+Law" target="_blank" title = "Submit Amdahl’s Law to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/12/amdahl-s-law.aspx&amp;amp;phase=2" target="_blank" title = "Submit Amdahl’s Law to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/12/amdahl-s-law.aspx&amp;amp;title=Amdahl%e2%80%99s+Law" target="_blank" title = "Submit Amdahl’s Law to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/12/amdahl-s-law.aspx&amp;amp;title=Amdahl%e2%80%99s+Law" target="_blank" title = "Submit Amdahl’s Law to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/linchi_shea/archive/2008/02/12/amdahl-s-law.aspx&amp;amp;title=Amdahl%e2%80%99s+Law&amp;amp;;top=1" target="_blank" title = "Add Amdahl’s Law to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5042" width="1" height="1"&gt;</content><author><name>Linchi Shea</name><uri>http://sqlblog.com/members/Linchi+Shea.aspx</uri></author><category term="Performance" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Performance/default.aspx" /><category term="Architecture" scheme="http://sqlblog.com/blogs/linchi_shea/archive/tags/Architecture/default.aspx" /></entry></feed>