<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Thomas Kejser&#039;s Database Blog</title>
	<atom:link href="http://blog.kejser.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.kejser.org</link>
	<description>Fighting bad Data Modeling</description>
	<lastBuildDate>Tue, 21 May 2013 16:10:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.kejser.org' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/ce0fc1bca7cb608b3830d115543e7a5e?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Thomas Kejser&#039;s Database Blog</title>
		<link>http://blog.kejser.org</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.kejser.org/osd.xml" title="Thomas Kejser&#039;s Database Blog" />
	<atom:link rel='hub' href='http://blog.kejser.org/?pushpress=hub'/>
		<item>
		<title>Bottleneck Diagnosis on SQL Server &#8211; New Scripts</title>
		<link>http://blog.kejser.org/2013/04/11/bottleneck-diagnosis-on-sql-server-new-scripts/</link>
		<comments>http://blog.kejser.org/2013/04/11/bottleneck-diagnosis-on-sql-server-new-scripts/#comments</comments>
		<pubDate>Thu, 11 Apr 2013 15:42:44 +0000</pubDate>
		<dc:creator>Thomas Kejser</dc:creator>
				<category><![CDATA[Grade of the Steel]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[FusionIO]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Tuning]]></category>

		<guid isPermaLink="false">https://kejserbi.wordpress.com/?p=868</guid>
		<description><![CDATA[Finally, I have found some time with my good colleagues at Fusion-io to work on some of my old SQL Scripts. Our first script queries the servers for wait stats &#8211; a very common task for nearly all SQL Server DBAs. This is the first thing I do when I meet a new SQL Server [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=868&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Finally, I have found some time with my good colleagues at <a class="zem_slink" title="Fusion-io" href="http://www.fusionio.com/" target="_blank" rel="homepage">Fusion-io</a> to work on some of my old SQL Scripts.</p>
<p>Our first script queries the servers for wait stats &#8211; a very common task for nearly all <a class="zem_slink" title="Microsoft SQL Server" href="http://www.microsoft.com/sqlserver" target="_blank" rel="homepage">SQL Server</a> DBAs. This is the first thing I do when I meet a new SQL Server installation and I have generally found that I apply the same filters over and over again. Because of this, I worked with Sumeet Bansal to standardise our approach to this.</p>
<p>You can watch Sumeet introduce the script in this YouTube video: <a title="http://youtu.be/zb4FsXYvibY" href="http://youtu.be/zb4FsXYvibY">http://youtu.be/zb4FsXYvibY</a>. A TV star is born!</p>
<p>We have already used this script at several customers in a before/after Fusion-io situation. As you may know, the tuning game changes a lot when you remove the I/O bottleneck from the server.</p>
<p>Based on our experiences so far, I wanted to share some more exotic waits and latches we have been seeing lately.</p>
<p><span id="more-868"></span></p>
<h3>WRITELOG</h3>
<p>This is not exotic at all you may say. In fact, it is probably the most common wait type in most SQL Server installations.</p>
<p>Here is what you may not know: This wait does NOT measure the I/O latency of the log drive. To get that, you have to query the log file in <strong>sys.dm_io_virtual_file_stats</strong> – which you may notice often reports a lower wait time than <strong>WRITELOG</strong>. Just something to think about when measuring log latency as we see a larger and large discrepancy between this wait and the actual I/O wait.</p>
<p>I have provided more details on this in my SQLBits presentations:</p>
<ul>
<li><a href="http://sqlbits.com/Sessions/Event9/Finding_the_Limits">Finding the Limits</a> (Presentation from SQLBits 9)</li>
</ul>
<h3>ACCESS_METHOD_DATASET_PARENT</h3>
<p>We are seeing this latch wait a lot, especially in data warehouse environments. It is related to parallelism. While lowering MAXDOP is one way to remove it – it is not always the optimal way and you may not get the most out of your hardware if you do.</p>
<p>We typically see this wait happening in two different situations:</p>
<ol>
<li>When doing table scans</li>
<li>When running <strong>INSERT…SELECT</strong> as part of an ETL process</li>
</ol>
<p>In both cases, the wait indicates that you are hitting some form of scalability issue. My friend Henk van der Valk blogged about how to work around the table scan problem:</p>
<ul>
<li><a href="http://henkvandervalk.com/maximizing-sql-server-2008-r2-table-scan-speed-from-dsi-solid-state-storage">Maximizing SQL Server 2008R2 table scan speeds</a></li>
</ul>
<p>Henk used another type of non volatile storage: battery backed DRAM; the lesson he learned is equally applicable to Fusion-io.</p>
<p>I have written about optimising <strong>INSERT…SELECT</strong> in this whitepaper:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/dd425070(v=sql.100).aspx">The Data Loading Performance Guide</a></li>
</ul>
<ul>There is probably another blog entry to be written one day.</ul>
<h3>PAGELATCH_UP</h3>
<p>Typically, we see this wait when a filegroup in a database doesn’t have enough files allocated. It is easy to diagnose: just look for PFS pages in the <strong>resource_description</strong>. Yes, this applies to user databases too, not just <strong>tempdb</strong>.</p>
<p>How many data files you should have in a database or filegroup has been debated a lot in the SQL Server community, <a href="http://sqlcat.com/sqlcat/b/technicalnotes/archive/2008/03/07/how-many-files-should-a-database-have-part-1-olap-workloads.aspx">even by me</a>. When running on spindles (or spinning rust as we like to call it in Fusion-io) the answer is a big “it depends”. But on flash our experience and our benchmarking has shown that more is better, especially under high concurrency workloads.</p>
<p><a href="http://kejserbi.files.wordpress.com/2013/04/image.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" alt="image" src="http://kejserbi.files.wordpress.com/2013/04/image_thumb.png?w=596&#038;h=372" width="596" height="372" border="0" /></a></p>
<p><em>Above: Runtime and PAGELATCH_UP waits when adding more data files. Notice the sharp drop from 1 to 8 and that the runtime curve continue to drop as you add more files</em></p>
<p>There is enough material for another blog entry (and for some nice new scripts) on this subject.</p>
<h3>PAGELATCH_EX</h3>
<p>Another common wait. Typically, this occurs in two situations:</p>
<ol>
<li>When you issue <strong>UPDATE</strong> statements a lot against small tables</li>
<li>When you run many concurrent <strong>INSERT</strong> statements into a table that has an index on an IDENTITY or NEWSEQUENTIALID column</li>
<li>When using a table as the backing store for a message queue</li>
</ol>
<p><strong>Ad 1)</strong> The solution to situation 1 is normally to “pad” the table with a CHAR(4000) NOT NULL column to make every single row fit only one page. However, this is only viable on small tables – but those are the ones that tend to see this effect.</p>
<p><strong>Ad 2)</strong> For high scale systems powered by flash memory, our recommendation for generating keys goes directly against the typical approach taken by the SQL Server community. DO NOT use <strong>IDENTITY</strong>, <strong>SEQUENCER</strong> or <strong>NEWSEQUENTIALID</strong> to generate keys. In fact, we have found that the old and despised  <strong>NEWID</strong> is significantly faster than <strong>NEWSEQUENTIALID</strong>. The numbers speak for themselves, here is the runtime of a workload that inserts 160M rows:</p>
<p><a href="http://kejserbi.files.wordpress.com/2013/04/image1.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" alt="image" src="http://kejserbi.files.wordpress.com/2013/04/image_thumb1.png?w=543&#038;h=267" width="543" height="267" border="0" /></a></p>
<p><em>Above: Myth busting “best practises” for generating keys.</em></p>
<p>There is a very interesting solution to the key generation problem that has been blogged about by another friend of mine, here is the link to Rick’s very elegant key generator:</p>
<ul>
<li><a href="http://dangerousdba.blogspot.co.uk/2011/10/bit-reversion.html">Bit Reversion</a></li>
</ul>
<p><strong>Ad 3)</strong> I have previously blogged about the design pattern that solves this problem</p>
<ul>
<li><a href="http://blog.kejser.org/2012/05/25/implementing-message-queues-in-relational-databases/">Implementing Message Queues in Relational Databases</a></li>
</ul>
<h3>Summary</h3>
<p>As we install more and more Fusion-io into <a class="zem_slink" title="SQL" href="http://www.iso.org/iso/catalogue_detail.htm?csnumber=45498" target="_blank" rel="homepage">SQL Servers</a> and remove the I/O problem, we continue to learn about new bottlenecks in typical customer workloads and how to solve them. Through our understanding of the full application stack, we are helping customers get more out of their new hardware. I run a mentoring program inside the company where our field unit, always eager for more knowledge, learn how to tune even very complex problems in SQL Server.</p>
<p>In Fusion-io, we live every day in the world beyond the I/O problem, and we are privileged to be the first to witness the disruption NAND flash is creating in the market. We are especially excited about <a href="http://blogs.technet.com/b/dataplatforminsider/archive/2012/12/11/how-fast-is-project-codenamed-hekaton-it-s-wicked-fast.aspx">Project Hekaton</a> and how that is going to change the game once again. As we explore Hekaton, we will adjust our guidance. The SQL community has a lot to look forward to from Microsoft and we look forward to continuing to provide acceleration in this space.</p>
<p>I would like to thank my colleagues in Fusions Data Propulsion Labs for helping making all this come together – especially Sumeet Bansal the new face of our SQL Server YouTube series.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kejserbi.wordpress.com/868/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kejserbi.wordpress.com/868/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=868&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kejser.org/2013/04/11/bottleneck-diagnosis-on-sql-server-new-scripts/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<georss:point>51.501985 -0.298745</georss:point>
		<geo:lat>51.501985</geo:lat>
		<geo:long>-0.298745</geo:long>
		<media:content url="http://0.gravatar.com/avatar/93e3150ebaf2321aef3dc4faee057861?s=96&#38;d=retro&#38;r=G" medium="image">
			<media:title type="html">schastar42</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2013/04/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2013/04/image_thumb1.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Quantifying the Cost of Compression</title>
		<link>http://blog.kejser.org/2013/03/11/quantifying-the-cost-of-compression/</link>
		<comments>http://blog.kejser.org/2013/03/11/quantifying-the-cost-of-compression/#comments</comments>
		<pubDate>Mon, 11 Mar 2013 04:03:34 +0000</pubDate>
		<dc:creator>Thomas Kejser</dc:creator>
				<category><![CDATA[Grade of the Steel]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Compression]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">https://kejserbi.wordpress.com/?p=863</guid>
		<description><![CDATA[Last week, at SQL Saturday Exeter, I did a new Grade of Steel experiment: to quantify just how expensive it is to do PAGE compression. The presentation is a 45 minute show, but for those of you who were not there, here is a summary of the highlights of the first part. My tests were [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=863&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Last week, at SQL Saturday Exeter, I did a new Grade of Steel experiment: to quantify just how expensive it is to do PAGE compression.</p>
<p>The presentation is a 45 minute show, but for those of you who were not there, here is a summary of the highlights of the first part.</p>
<p>My tests were all run on the TPC-H LINEITEM table at scale factor 10. That is about 6.5GB of data.</p>
<h3>Test: Table Scan of Compressed Data</h3>
<p>My initial test is this statement:</p>
<blockquote><p><font face="Consolas"><strong>SELECT</strong> MAX(L_SHIPDATE)        <br />, MAX(L_DISCOUNT)        <br />, MAX(L_EXTENDEDPRICE)        <br />, MAX(L_SUPPKEY)        <br />, MAX(L_QUANTITY)        <br />, MAX(L_RETURNFLAG)        <br />, MAX(L_PARTKEY)        <br />, MAX(L_LINESTATUS)        <br />, MAX(L_TAX)        <br />, MAX(L_COMMITDATE)        <br />, MAX(L_RECEIPTDATA)        <br /><strong>FROM</strong> LINEITEM</font></p>
</blockquote>
<p>Because the statement only returns one row, the result measured does not drown in client transfer time. Instead, the raw cost of extracting the columns from the compressed format can be quantified.</p>
<p>The result was quite shocking on my home 12 core box:</p>
<p><a href="http://kejserbi.files.wordpress.com/2013/03/image1.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2013/03/image_thumb1.png?w=526&#038;h=117" width="526" height="117" /></a></p>
<p>Even when doing I/O, it still takes quite a bit longer to scan the compressed format. And when scanning from DRAM, the cost is a whopping 2x.</p>
<p>A quick <strong>xperf</strong> run shows where the time goes when scanning from memory</p>
<p><a href="http://kejserbi.files.wordpress.com/2013/03/image2.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2013/03/image_thumb2.png?w=280&#038;h=186" width="280" height="186" /></a></p>
<p>Indeed, the additional CPU cost explains the effect. The code path is simply longer with compression.</p>
<h3>Test: Singleton Row fetch</h3>
<p>By sampling some rows from LINEITEM, it is possible to measure the cost of fetching pages in an index seek. This is the test:</p>
<blockquote><p><font face="Consolas"><strong>SELECT</strong> MAX(L_SHIPDATE)        <br />, MAX(L_DISCOUNT)        <br />, MAX(L_EXTENDEDPRICE)        <br />, MAX(L_SUPPKEY)        <br />, MAX(L_QUANTITY)        <br />, MAX(L_RETURNFLAG)        <br />, MAX(L_PARTKEY)        <br />, MAX(L_LINESTATUS)        <br />, MAX(L_TAX)        <br />, MAX(L_COMMITDATE)        <br />, MAX(L_RECEIPTDATA)         <br /><strong>FROM</strong> LI_SAMPLES S        <br /></font><font face="Consolas"><strong>INNER LOOP JOIN</strong> LINEITEM L <strong>ON</strong> S.L_ORDERKEY = L.L_ORDERKEY        <br /><strong>OPTION (MAXDOP 1)</strong>&#160;</font></p>
</blockquote>
<p>This gives us the plan:</p>
<p><a href="http://kejserbi.files.wordpress.com/2013/03/image3.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2013/03/image_thumb3.png?w=463&#038;h=172" width="463" height="172" /></a></p>
<p>Which has the desired characteristics of having the runtime dominated by the seek into the LINEITEM table.</p>
<p>The numbers again speak for themselves:</p>
<p><a href="http://kejserbi.files.wordpress.com/2013/03/image4.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2013/03/image_thumb4.png?w=462&#038;h=138" width="462" height="138" /></a></p>
<p>And again, the <strong>xperf</strong> trace shows that this runtime difference can be fully explained from longer code paths.</p>
<h3>Test: Singleton UPDATE</h3>
<p>Using the now familiar pattern, we can run a test that updates the rows instead of selecting them. By updating a column that is NOT NULL and an INT, we can make sure the update happens in place. This means we pay the price to decompress, change and recompress that row – which should be more expensive than reading. And indeed it is:</p>
<p><a href="http://kejserbi.files.wordpress.com/2013/03/image5.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2013/03/image_thumb5.png?w=461&#038;h=137" width="461" height="137" /></a></p>
<h3>Summary</h3>
<p>Quoting a few of my tests from my&#160; presentation, I have shown you that PAGE compression carries a very heavy CPU cost for each page access. Of course, not every workload is dominated by accessing data in pages – some are more compute heavy on the returned data. However, in these days when I/O bottlenecks can easily be removed, it is worth considering if the extra CPU cycles to save space are worth it.</p>
<p>It turns out that it is possible to also show another expected results: that locks are held longer when updating compressed pages (Thereby limiting scalability if the workload contains heavily contended pages). But that is the subject of a new blog entry.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kejserbi.wordpress.com/863/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kejserbi.wordpress.com/863/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=863&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kejser.org/2013/03/11/quantifying-the-cost-of-compression/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/93e3150ebaf2321aef3dc4faee057861?s=96&#38;d=retro&#38;r=G" medium="image">
			<media:title type="html">schastar42</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2013/03/image_thumb1.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2013/03/image_thumb2.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2013/03/image_thumb3.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2013/03/image_thumb4.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2013/03/image_thumb5.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>More Courses Available &#8211; in Sweden and UK!</title>
		<link>http://blog.kejser.org/2013/01/11/more-courses-available-in-sweden-and-uk/</link>
		<comments>http://blog.kejser.org/2013/01/11/more-courses-available-in-sweden-and-uk/#comments</comments>
		<pubDate>Fri, 11 Jan 2013 17:16:29 +0000</pubDate>
		<dc:creator>Thomas Kejser</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://kejserbi.wordpress.com/?p=846</guid>
		<description><![CDATA[I am happy to announce that my tuning course and newly developed Data Warehousing course is now available. Tuning/Scaling Course The tuning course will be hosted by CrossJoin Consulting in London, UK You can sign up for it here: Tuning Course in London (13th June 2013) You can still make it for the early bird [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=846&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I am happy to announce that my tuning course and newly developed Data Warehousing course is now available.</p>
<h3>Tuning/Scaling Course</h3>
<p><a href="http://kejserbi.files.wordpress.com/2013/01/image.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;float:right;padding-top:0;border-width:0;" title="image" border="0" alt="image" align="right" src="http://kejserbi.files.wordpress.com/2013/01/image_thumb.png?w=195&#038;h=147" width="195" height="147" /></a>The tuning course will be hosted by CrossJoin Consulting in London, UK You can sign up for it here:</p>
<ul>
<li><a href="http://www.technitrain.com/coursedetail.php?c=21&amp;trackingcode=TK1">Tuning Course in London</a> (13th June 2013)</li>
</ul>
<p>You can still make it for the early bird rates. This course is probably THE deepest level course about SQL Server out there. You will learn the nitty-gritty details of xperf profiling, spinlock detection and multi-threaded optimisation.</p>
<p>We are going to be digging deep below the surface of SQL Server here, be prepared for an intensive day.</p>
<p>&#160;</p>
<h3>Data Warehousing Course</h3>
<p><a href="http://kejserbi.files.wordpress.com/2013/01/image1.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;float:right;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" align="right" src="http://kejserbi.files.wordpress.com/2013/01/image_thumb1.png?w=240&#038;h=154" width="240" height="154" /></a>The next data warehousing course will be in Kista, Sweden. It will be hosted by SolidQ and you can sign up for it here:</p>
<ul>
<li>
<div align="left"><a href="http://www.sqlserverutbildning.se/ViewEvent.aspx?eventId=1&amp;goback=%2Egna_2437138%2Egde_2437138_member_197242427">Data Warehousing in Sweden</a> (7th February 2013)</div>
</li>
</ul>
<p>This will be a very unique course with both Davide Mauri and myself teaching. Its a one day intensive training in my usual “no nonsense” style where you learn about data modeling from two of the leading experts in the field. The course extends the ideas I have blogged extensively about here.</p>
<p>There are still seats left, but they are going fast.</p>
<p>I look forward to seeing you there!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kejserbi.wordpress.com/846/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kejserbi.wordpress.com/846/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=846&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kejser.org/2013/01/11/more-courses-available-in-sweden-and-uk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/93e3150ebaf2321aef3dc4faee057861?s=96&#38;d=retro&#38;r=G" medium="image">
			<media:title type="html">schastar42</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2013/01/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2013/01/image_thumb1.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>VM-ware Shared folders are really Slow</title>
		<link>http://blog.kejser.org/2012/12/12/vm-ware-shared-folders-are-really-slow/</link>
		<comments>http://blog.kejser.org/2012/12/12/vm-ware-shared-folders-are-really-slow/#comments</comments>
		<pubDate>Wed, 12 Dec 2012 23:32:30 +0000</pubDate>
		<dc:creator>Thomas Kejser</dc:creator>
				<category><![CDATA[Grade of the Steel]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[I/O]]></category>
		<category><![CDATA[Tuning]]></category>
		<category><![CDATA[Virtualization]]></category>

		<guid isPermaLink="false">https://kejserbi.wordpress.com/?p=841</guid>
		<description><![CDATA[I am currently waiting for some code to compile and found a bit of time to type up a quick blog. As described in a previous post, I am have set up my laptop to host Windows in a virtual machine guest with Mac OX (Mountain Lion) as the host. Today, I needed to compile [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=841&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I am currently waiting for some code to compile and found a bit of time to type up a quick blog.</p>
<p>As described in a previous post, I am have set up my laptop to host Windows in a virtual machine guest with Mac OX (Mountain Lion) as the host. </p>
<p>Today, I needed to compile some code and thinking I was being clever, I put the code on the host OS (OSX) and shared the folder via VM-ware to the Windows guest OS.</p>
<h3>Compiling from inside VM-ware</h3>
<p>I ran my msbuild process from the shared folder, and it took FOREVER to compile. The obvious choice here is of course to blame virtualisation itself – after all, I only have 2 cores allocated to the virtual.</p>
<p>But not so fast! Our tuning knowledge comes in quite handy here. Have a look at the CPU pattern while I am compiling:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/12/image6.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb6.png?w=634&#038;h=102" width="634" height="102" /></a></p>
<p>Just like with SQL Server, I start my tuning at a very high level (in this case, task manager) and dig in from there. </p>
<p>The first question we ask ourselves as tuners is: Does what I see make sense?</p>
<p>In this case, it obviously doesn’t. MSBUILD is set up to build highly parallelised, it should be using my cores and there are no obvious I/O bottleneck in the system. Having 50% of two cores busy (and with high kernel times) looks a lot like a single threaded bottleneck to me. The build was taking over 15 minutes, which was much longer than expected.</p>
<h3>Diagnosing the Problem – our friend Xperf</h3>
<p>Normally, I use xperf to troubleshoot servers. But it sure comes in handy for misbehaving client machines too.</p>
<p>Task manager only shows that the time is spend in the process <strong>d.exe</strong> – which is part of the build process. Is the compiler bad or must we look elsewhere? Sure would be surprising if the compiler used all the kernel time wouldn’t it?</p>
<p>Here is the quick and dirty CPU “zoom in” xperf command to get the details we need:</p>
<ul>
<li><strong>xperf –on latency –stackwalk profile</strong></li>
<li><strong>…wait a bit</strong></li>
<li><strong>xperf –d &lt;myfile&gt;.etl</strong></li>
</ul>
<p>This captures a sample of the stack and CPU usage of each process and kernel module. From here, it is quite clear what is going on – let me walk you through the analysis. </p>
<p>First, open the trace with <strong>xperfview</strong>. I recommend staying with the Win7 version of xperfview, as the Win8 interface is… well… a Win8 interface.</p>
<p>Pick the <strong>CPU Sampling per CPU</strong>, right click and choose <strong>Summary Table</strong>:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/12/image7.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb7.png?w=709&#038;h=313" width="709" height="313" /></a></p>
<p>From here, pick the columns: <strong>Module</strong>, <strong>CPU</strong> and <strong>% Weight</strong> which allows you to summarise by module. On my box, it looks like this:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/12/image8.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb8.png?w=350&#038;h=255" width="350" height="255" /></a></p>
<p>Aha!… Most of the CPU burn goes in <strong>vmci.sys </strong>(just ignore<strong> intelppm.sys)</strong>. This isn’t a part of Windows. Its relatively easy to trace this file back to VM-ware.</p>
<p>So, who calls into this kernel module? Adding the stack column after the module, we can see that too:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/12/image9.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb9.png?w=402&#038;h=261" width="402" height="261" /></a></p>
<p>Eureka: It is file system access that is causing the slowdown. See the call stack? Starts from <strong>GetFileAttributesW</strong> and ends up inside <strong>vmci.sys</strong>.</p>
<h3>Fixing the problem</h3>
<p>Now, before you go ahead and conclude that VMware adds a horrible overhead to I/O, lets just try to move the source files into the guest OS itself. Recall that my machine is using VM-ware shared folders to access the source code. It might simply be the sharing framework that is acting strange…</p>
<p>The results of using the guest OS’s file system is staggering. Running the build process now looks like this at the CPU level:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/12/image10.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb10.png?w=578&#038;h=95" width="578" height="95" /></a></p>
<p>And the total build time is <strong><font color="#ff0000">down from over 15 minutes to less than 3 minutes</font></strong>.</p>
<p>Thank you xperf…</p>
<p>&#160;</p>
<p>&#160;</p>
<p>&#160;</p>
<p>&#160;</p>
<p>&#160;</p>
<p>&#160;</p>
<p>&#160;</p>
<p>At this point, we are reduced to guessing what is going on</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kejserbi.wordpress.com/841/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kejserbi.wordpress.com/841/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=841&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kejser.org/2012/12/12/vm-ware-shared-folders-are-really-slow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/93e3150ebaf2321aef3dc4faee057861?s=96&#38;d=retro&#38;r=G" medium="image">
			<media:title type="html">schastar42</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb6.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb7.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb8.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb9.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb10.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Configuring Kernel Debugging with WinDbg and a NULL modem</title>
		<link>http://blog.kejser.org/2012/12/05/configuring-kernel-debugging-with-windbg-and-a-null-modem/</link>
		<comments>http://blog.kejser.org/2012/12/05/configuring-kernel-debugging-with-windbg-and-a-null-modem/#comments</comments>
		<pubDate>Wed, 05 Dec 2012 18:25:23 +0000</pubDate>
		<dc:creator>Thomas Kejser</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Tuning]]></category>

		<guid isPermaLink="false">https://kejserbi.wordpress.com/?p=829</guid>
		<description><![CDATA[Lately, I have been digging deep into Windows to get really low level with the the I/O path SQL Server takes (yep, there is an even deeper layer to understand fully). Once you start playing around with the Windows Kernel, you will at some point need kernel level debugging set up. Traditionally, this is something [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=829&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://kejserbi.files.wordpress.com/2012/12/image.png"><img style="background-image:none;margin:0 0 0 6px;padding-left:0;padding-right:0;display:inline;float:right;padding-top:0;border-width:0;" title="image" border="0" alt="image" align="right" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb.png?w=184&#038;h=244" width="184" height="244" /></a>Lately, I have been digging deep into Windows to get really low level with the the I/O path SQL Server takes (yep, there is an even deeper layer to understand fully).</p>
<p>Once you start playing around with the Windows Kernel, you will at some point need kernel level debugging set up. Traditionally, this is something I have used a Windows machine for, and even there, it can be painful to get working. As you may know, I have switched to Mac as my client machine and my Windows utilities (including <strong>WinDbg</strong>) now run in VMWare Fusion – it looked like I was heading into an interop nightmare… </p>
<p>Windows 8 allows kernel debugging directly over the network card, but how does one configure kernel debugging with a Windows 2008R2 target from a Mac with VM Ware?</p>
<p>I found a very cheap solution today. You need:</p>
<ul>
<li>A USB to Serial (RS-232) converter </li>
<li>A NULL modem (I would recommend getting a long one, so you don’t have to sit next to the server)</li>
<li>A&#160; target server that you want to debug </li>
<li>A serial port on the target server </li>
<li>WinDbg from the Windows SDK in a virtual machine on the Mac</li>
<li>Symbols set up as per my <a href="http://blog.kejser.org/2012/03/14/setting-yourself-up-for-debugging/">previous post</a> </li>
</ul>
<p>A USB converter and a NULL modem is a dirt cheap way to get the required hardware for kernel debugging. I sourced my cables from <a href="http://www.maplin.co.uk/">Maplins</a> (Thanks @SQLServerMonkey) in the UK – for a total of around 20 GBP.</p>
<h3>Step 1: Prepare the Client/Debugger</h3>
<p>A Macbook air, like most other lightweight laptops, does not have a serial port. So, we have to use a USB/Serial converter. It is possible to debug directly over USB, but good luck with that from a Mac, I didn’t have the courage. </p>
<p>Make sure VMWare routes the USB device to the Windows Guest OS and not the Mac. It will look something like this in VMWare Fusion 5:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/12/image1.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb1.png?w=461&#038;h=185" width="461" height="185" /></a></p>
<p>Now, install <strong>WinDbg</strong> and set up your symbol paths if they are not set up already.</p>
<p>Check your Device Manager in the client to see which COM port the USD device created. As you can see below, my laptop mounted the USB/Serial converter as <strong>COM3</strong>&#160;</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/12/image2.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb2.png?w=314&#038;h=335" width="314" height="335" /></a></p>
<p>&#160;</p>
<p>After installing the device, I had to restart my virtual machine before VMWare would let me mount it – but what can you expect from a 10 GBP component? Your mileage may vary depending on the serial/USB driver you have.</p>
<h3>Step 2: Connect Client and Server</h3>
<p>Using the NULL modem, connect the USB/Serial converter to the server’s Serial port. </p>
<p>Make sure the server has the serial port enabled in the BIOS (my Dell box had it disabled, had to re-enable). </p>
<h3>Step 3: Configure Server/Debugee for kernel debugging</h3>
<p>Log into the server, start a command line as administrator</p>
<p>First, copy the default startup options into a new boot option:</p>
<ul>
<li><font face="Consolas"><strong>BCDEDIT /copy {current} /d DebugMode</strong></font> </li>
</ul>
<p>This will create a new entry in the boot list when the server starts. Make a note of the GUID returned or copy it to the clipboard (using the ever so annoying copy/paste function in the Windows command prompt)</p>
<p>Next, configure the parameters for serial cable debugging:</p>
<ul>
<li><strong><font face="Consolas">BCDEDIT /set &lt;GUID&gt; debugport &lt;port #&gt;</font></strong></li>
<li><font face="Consolas"><strong>BCDEDIT /set &lt;GUID&gt; debugtype serial </strong></font></li>
<li><font face="Consolas"><strong>BCDEDIT /set &lt;GUID&gt; baudrate 115200</strong></font> </li>
</ul>
<p>Replace the <strong>&lt;GUID&gt;</strong> the guid returned previously. Set <strong>&lt;port #&gt;</strong> to the COM port the NULL modem is connected to in your server (NOT the COM port of the client). For example, if the server has the NULL modem in COM2, set &lt;port #&gt; to 2. </p>
<p>Finally, enable debugging for on the newly created boot option:</p>
<ul>
<li><font face="Consolas">BCDEDIT /debug &lt;GUID&gt; ON</font> </li>
</ul>
<p>Validate that your configuration works by running:</p>
<ul>
<li><strong><font face="Consolas">BCDEDIT /v</font></strong>. </li>
</ul>
<p>You should get an output somewhat like this (this is also how you find the GUID if you didn’t note it down before):</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/12/image3.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb3.png?w=458&#038;h=195" width="458" height="195" /></a></p>
<p>If you want to make sure debugging is always turned on (great for a sandbox machines where you explore stuff in the kernel) you can use <strong><font face="Consolas">BCDEDIT /default &lt;GUID&gt;</font></strong> to make debugging the default startup option.</p>
<h3>Step 3: Start Debugging</h3>
<p>You are now ready to start debugging the windows kernel on the server. Here is how:</p>
<p>On the client, start WinDbg and choose <strong>File—&gt;Kernel Debug</strong> (or CTRL+K) and set up the com port you got in step 1:</p>
<p>. <a href="http://kejserbi.files.wordpress.com/2012/12/image4.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb4.png?w=314&#038;h=256" width="314" height="256" /></a></p>
<p>Press OK, and reboot the server. If you didn’t select the debug configuration as the default boot option, make sure you pick it when the server starts. </p>
<p>If you have done things right, you will get something like this in <strong>WinDbg</strong> (below, I broke execution with CTRL+C)</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/12/image5.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/12/image_thumb5.png?w=600&#038;h=296" width="600" height="296" /></a></p>
<p>One thing to note when you are debugging the kernel: Not all your typical <strong>WinDbg</strong> commands work as they normally do (for some good reasons), but that is outside of scope for this blog entry.</p>
<p>Time to dig in even deeper… my Macbook Air to a Windows box <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> …Happy hacking everyone.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kejserbi.wordpress.com/829/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kejserbi.wordpress.com/829/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=829&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kejser.org/2012/12/05/configuring-kernel-debugging-with-windbg-and-a-null-modem/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/93e3150ebaf2321aef3dc4faee057861?s=96&#38;d=retro&#38;r=G" medium="image">
			<media:title type="html">schastar42</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb1.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb2.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb3.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb4.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/12/image_thumb5.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Sharing Slides on SlideShare.net</title>
		<link>http://blog.kejser.org/2012/10/09/sharing-slides-on-slideshare-net/</link>
		<comments>http://blog.kejser.org/2012/10/09/sharing-slides-on-slideshare-net/#comments</comments>
		<pubDate>Tue, 09 Oct 2012 15:21:07 +0000</pubDate>
		<dc:creator>Thomas Kejser</dc:creator>
				<category><![CDATA[Public Speaking]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Conference]]></category>
		<category><![CDATA[Slides]]></category>

		<guid isPermaLink="false">https://kejserbi.wordpress.com/?p=815</guid>
		<description><![CDATA[Hey everyone. Just a short post to let you know I am now sharing some of my slide decks from conferences at SlideShare. Here is the URL: http://www.slideshare.net/tkejser1 Some things I put there so far: The Fusion Fireside talk I did at SQL Bits (which shows SQL based message queues in action) My Big Data [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=815&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Hey everyone. Just a short post to let you know I am now sharing some of my slide decks from conferences at SlideShare. Here is the URL:</p>
<ul>
<li><a title="http://www.slideshare.net/tkejser1" href="http://www.slideshare.net/tkejser1">http://www.slideshare.net/tkejser1</a> </li>
</ul>
<p>Some things I put there so far:</p>
<ul>
<li>The Fusion Fireside talk I did at SQL Bits (which shows SQL based message queues in action) </li>
<li>My Big Data vs. DW deck (as seen at SQL PASS 2012 and other conferences) </li>
<li>A deck I created to introduce storage people to databases </li>
</ul>
<ul>Feel free to use the material, I only ask that you let people know where you got it from.</ul>
<p>My old slide decks belongs to MS as their IP, so I can’t share those slides with you. However, you will often find some of that material is available for download at the conference site where I presented it. For example, you can find a lot of my presentations on the SQL Bits website here:</p>
<ul>
<li><a title="http://www.sqlbits.com/Speakers/Thomas_Kejser" href="http://www.sqlbits.com/Speakers/Thomas_Kejser">http://www.sqlbits.com/Speakers/Thomas_Kejser</a></li>
</ul>
<p> Next week, I will be presenting at IP Expo about the Fusion-io SDK initiative. Exciting times.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kejserbi.wordpress.com/815/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kejserbi.wordpress.com/815/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=815&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kejser.org/2012/10/09/sharing-slides-on-slideshare-net/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/93e3150ebaf2321aef3dc4faee057861?s=96&#38;d=retro&#38;r=G" medium="image">
			<media:title type="html">schastar42</media:title>
		</media:content>
	</item>
		<item>
		<title>One Million IOPS on a 2 socket server</title>
		<link>http://blog.kejser.org/2012/09/27/one-million-iops-on-a-2-socket-server/</link>
		<comments>http://blog.kejser.org/2012/09/27/one-million-iops-on-a-2-socket-server/#comments</comments>
		<pubDate>Thu, 27 Sep 2012 21:06:15 +0000</pubDate>
		<dc:creator>Thomas Kejser</dc:creator>
				<category><![CDATA[Grade of the Steel]]></category>
		<category><![CDATA[FusionIO]]></category>
		<category><![CDATA[I/O]]></category>

		<guid isPermaLink="false">https://kejserbi.wordpress.com/?p=813</guid>
		<description><![CDATA[Today, using Fusion ioMemory technology, I worked with our team of experts to hit 1M 4K random read IOPS on Windows. We did this on a 2-socket Sandy Bridge Server. Below is the screenshot to prove it: Think for a moment about what it will take to actually make use of all those IOPS. If [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=813&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Today, using Fusion ioMemory technology, I worked with our team of experts to hit 1M 4K random read IOPS on Windows. We did this on a 2-socket Sandy Bridge Server. </p>
<p>Below is the screenshot to prove it:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/09/image.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/09/image_thumb.png?w=544&#038;h=166" width="544" height="166" /></a></p>
<p>Think for a moment about what it will take to actually make use of all those IOPS. If this is the type of speed you have at your disposal, maybe it is time to rethink what is possible. Check out our SDK at <a href="http://developer.fusionio.com">http://developer.fusionio.com</a> for the leading edge work Fusion-io is doing in this space.</p>
<p>As I am sure my regular readers&#160; can guess, I am loving my new job!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kejserbi.wordpress.com/813/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kejserbi.wordpress.com/813/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=813&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kejser.org/2012/09/27/one-million-iops-on-a-2-socket-server/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/93e3150ebaf2321aef3dc4faee057861?s=96&#38;d=retro&#38;r=G" medium="image">
			<media:title type="html">schastar42</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/09/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>First publicly available courses &#8211;in Aarhus, Denmark &#8211; 23-24 October</title>
		<link>http://blog.kejser.org/2012/08/30/first-publicly-available-coursein-aarhus-denmark/</link>
		<comments>http://blog.kejser.org/2012/08/30/first-publicly-available-coursein-aarhus-denmark/#comments</comments>
		<pubDate>Thu, 30 Aug 2012 09:29:16 +0000</pubDate>
		<dc:creator>Thomas Kejser</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://kejserbi.wordpress.com/?p=806</guid>
		<description><![CDATA[I am pleased to announce that both my Tuning Course and the Data Warehouse Modeling course will be run in Aarhus Denmark. The courses will be held in English, even though they are hosted in the very city I was born. The course will be hosted by Orangeman, who will be handling the logistics. There [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=806&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I am pleased to announce that both my Tuning Course and the Data Warehouse Modeling course will be run in Aarhus Denmark. The courses will be held in English, even though they are hosted in the very city I was born.</p>
<p>The course will be hosted by Orangeman, who will be handling the logistics. There are still available spots and if you act fast, you can get the early bird price.</p>
<p>The relevant details:</p>
<ul>
<li>23rd October 2012: <a href="http://orangeman.dk/kursuskatalog/Tuning-Diagnosing-and-Fixing-hard-problems/">Tuning Course</a></li>
<li>24th October 2012: <a href="http://orangeman.dk/kursuskatalog/DW-Modeling-Make-the-Right-Choices/">Data Warehouse modeling</a></li>
</ul>
<p>See you there for some intense days of tuning and modeling.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kejserbi.wordpress.com/806/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kejserbi.wordpress.com/806/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=806&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kejser.org/2012/08/30/first-publicly-available-coursein-aarhus-denmark/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/93e3150ebaf2321aef3dc4faee057861?s=96&#38;d=retro&#38;r=G" medium="image">
			<media:title type="html">schastar42</media:title>
		</media:content>
	</item>
		<item>
		<title>Joining FusionIo</title>
		<link>http://blog.kejser.org/2012/08/10/joining-fusionio/</link>
		<comments>http://blog.kejser.org/2012/08/10/joining-fusionio/#comments</comments>
		<pubDate>Fri, 10 Aug 2012 14:56:44 +0000</pubDate>
		<dc:creator>Thomas Kejser</dc:creator>
				<category><![CDATA[Grade of the Steel]]></category>
		<category><![CDATA[Public Speaking]]></category>
		<category><![CDATA[Conference]]></category>
		<category><![CDATA[FusionIO]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[I/O]]></category>

		<guid isPermaLink="false">https://kejserbi.wordpress.com/?p=804</guid>
		<description><![CDATA[I am very happy to announce that I have signed a contract with FusionIo and will be joining them as CTO of EMEA from 1st September 2012. As many of you know, I have worked together with FusionIo on many occasions&#160; and really enjoyed the collaboration. I believe that their products hold the keys to [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=804&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://kejserbi.files.wordpress.com/2012/08/image.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;float:right;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" align="right" src="http://kejserbi.files.wordpress.com/2012/08/image_thumb.png?w=124&#038;h=120" width="124" height="120" /></a>I am very happy to announce that I have signed a contract with <a href="http://www.fusionio.com">FusionIo</a> and will be joining them as CTO of EMEA from 1st September 2012. </p>
<p>As many of you know, I have worked together with FusionIo on many occasions&#160; and really enjoyed the collaboration. I believe that their products hold the keys to a new era of computing and it is an honour to join their ranks. I will be looking forward to doing a lot of exciting research and customer implementations for them.</p>
<p>This brings me to the work I have been doing since I left Microsoft. Here is how it will transfer:</p>
<h3>Consulting Contracts</h3>
<p>I have contracts with some customers open. These are all due to terminate before 1st September and I will of course honour my agreements here. Unfortunately, my new job will not allow me to continue the collaboration with these customers on a consulting basis after this. The good news is that <a href="http://blog.kejser.org/courses/">my courses</a> will still be available and I will be able to share my knowledge through this channel.</p>
<h3>Courses and Conferences</h3>
<p>Contributing information to the community is one of my great passions in life. FusionIo has allowed me to continue to pursue this interest. My courses will still be available, although only for a very limited amount of days every month as the course time will be coming out of my vacation days (hint on how to get a discount). I expect demand to be high. There are already&#160; three tuning courses set up across Europe which will be held as planned and a lot of people have made it clear they want more. I will be announcing the exact dates for courses planned on this blog soon and let you know how to join the courses that are open to the public. The material is looking amazing and is using the new format that has evolved at SQL BITS and driven the top scores there. I expect this will be my best presentations yet. I am also happy to announce that my data modelling course is well underway and will be available soon. </p>
<p>I will continue to submit abstracts for conferences and stay in close touch with the community, just like I have always done. And&#160; this brings me to:</p>
<h3>Grade of the Steel</h3>
<p>I am very excited that FusionIo has an interest in expanding the testing I have done with my <a href="http://blog.kejser.org/grade-of-the-steel/">Grade of the Steel Project</a>. I will continue to run benchmarks on the latest and greatest storage and provide non volatile memory specific configuration and tuning guidance. Exactly which format the publications will take is too early to say, I will keep you posted on this blog.    </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kejserbi.wordpress.com/804/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kejserbi.wordpress.com/804/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=804&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kejser.org/2012/08/10/joining-fusionio/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/93e3150ebaf2321aef3dc4faee057861?s=96&#38;d=retro&#38;r=G" medium="image">
			<media:title type="html">schastar42</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/08/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>What is the Best Sort Order for a Column Store?</title>
		<link>http://blog.kejser.org/2012/07/27/what-is-the-best-sort-order-for-a-column-store/</link>
		<comments>http://blog.kejser.org/2012/07/27/what-is-the-best-sort-order-for-a-column-store/#comments</comments>
		<pubDate>Fri, 27 Jul 2012 13:44:14 +0000</pubDate>
		<dc:creator>Thomas Kejser</dc:creator>
				<category><![CDATA[BigData]]></category>
		<category><![CDATA[Data Warehouse]]></category>
		<category><![CDATA[Grade of the Steel]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[Compression]]></category>
		<category><![CDATA[Statistics]]></category>

		<guid isPermaLink="false">https://kejserbi.wordpress.com/?p=800</guid>
		<description><![CDATA[As hinted at in my post about how column stores work, the compression you achieve will depend on how many repetitions (or “runs”) exist in the data for the sort order that is used when the index is built. In this post, I will provide you more background on the effect of sort order on [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=800&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>As hinted at in my post about <a href="http://blog.kejser.org/2012/07/04/how-do-column-stores-work/">how column stores work</a>, the compression you achieve will depend on how many repetitions (or “runs”) exist in the data for the sort order that is used when the index is built. In this post, I will provide you more background on the effect of sort order on compression and give you some heuristics you can use to save space and increase speed of column stores. This is a theory that I am still only developing, but the early results are promising.</p>
<p><span id="more-800"></span>
<p>To approach my theory, I am afraid we are going to have to dig into some concepts from information theory. </p>
<h3>Shared Context</h3>
<p>Compression works by eliminating superfluous information in a stream of data. Unfortunately, it is rather hard to grasp exactly what information is superfluous – as this depends not only on the representation of the data, but also on how much context is shared between the sender and receiver.</p>
<p>The best way I have found to describe this problem is the story about the author who, after having sent his new hit novel to the publisher for publication, went on vacation. After a week, the author sends the following postcard to the publisher from his vacation resort:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/07/image28.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/07/image_thumb28.png?w=240&#038;h=138" width="240" height="138" /></a></p>
<p>The publisher, without hesitation replies:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/07/image29.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/07/image_thumb29.png?w=240&#038;h=142" width="240" height="142" /></a></p>
<p>We all know what this information exchange conveys, because we know the context of the publisher’s and author’s conversation. Very little, if any, information is lost even though the amount of data transmitted is as low as it gets (a single byte).</p>
<p>Unfortunately, we are rarely in a situation where the shared information between sender and receiver is as large as this. We have to find a different way to quantify how much data can be thrown away while preserving the information content.</p>
<p style="padding-left:20px;padding-right:20px;"><em>Side note: The above story is not my own but borrowed from somewhere. Unfortunately, I fail to recall where I first read about it&#160; (it may have been Steven Pinker). If you know, I would appreciate if you could let me know the source so I can give proper credit.</em></p>
<h3>Low Entropy ≈ High Compression</h3>
<p>Formalising the information content of a data transmission turns out to be a hard concept to wrap your head around. Fortunately, this has not prevented both computer scientists, mathematicians and statisticians from making progress in this area.</p>
<p>Claude Shannon, working on signal compression first came up with the notion of <a href="http://en.wikipedia.org/wiki/Entropy_(information_theory)">Information Entropy</a>. You can read more in articles I will link throughout this blog.&#160; They describe the theory more elaborately than I can. </p>
<p>Roughly speaking the Entropy H(X) of a random variable, for our purposes the content of a database column, is the amount of uncertainty associated with given value of that column. Entropy is typically measured in bits. If the entropy of a column is low, we would expect that there are either very few values in the column or that they are unevenly distributed somehow. The maximum entropy of a column is achieved on keys and it goes down after after that.&#160; </p>
<p>Entropy of a column, X, is calculated as:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/07/image30.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/07/image_thumb30.png?w=240&#038;h=62" width="240" height="62" /></a></p>
<p>Where <strong>p(x<sub>i</sub>)</strong> is the probability of each value the column takes. We can calculate all these probabilities with SQL like this:</p>
<blockquote><p><font face="Consolas"><strong>SELECT</strong> X         <br />&#160; , CAST(COUNT(*) AS FLOAT) / SUM(COUNT(*)) OVER (PARTITION BY NULL) pX         <br /><strong>FROM</strong> Table         <br /><strong>GROUP BY</strong> X</font></p>
</blockquote>
<p>And we can get <strong>H(X)</strong> like this:</p>
<blockquote><p><font face="Consolas"><strong>SELECT</strong> -1 * SUM(pX * LOG(pX, 2)) AS H         <br /><strong>FROM</strong>         <br />(         <br />&#160;&#160;&#160; <strong>SELECT</strong> X         <br />&#160;&#160;&#160; , CAST(COUNT(*) AS FLOAT) / SUM(COUNT(*)) OVER (PARTITION BY NULL) pX         <br />&#160;&#160;&#160; <strong>FROM</strong> Table         <br />&#160;&#160;&#160; <strong>GROUP</strong> BY X         <br />) AS p         <br /></font></p>
</blockquote>
<p>Think of <strong>H(X)</strong> as an upper boundary for how much we can theoretically compress the column. This should also tell you why you cannot tell in advanced how well a compression algorithm will work until you have actually seen or fully described the data – anyone who claims otherwise are bending the truth. </p>
<p>In summary we can use the entropy as a rough estimate of how many bits it would take to fully describe the column and it also roughly correlates to the number of repetitions in the column (which is what we are after in column stores). So far so good…</p>
<h3>Mutual Information I(X;Y) and Variation of Information d(X,Y)</h3>
<p>With entropy, we can get a rough ranking of columns by their compressibility. This is generally useful, even for page/dictionary compression. In other words, entropy allows us to come up with good candidates for columns to lead a clustered index on a fact table.</p>
<p>However, in column stores, we want to take this one step further. We are interested in how columns relate <em>to each other</em>, so we can group similar columns together during the index build phase and achieve even fewer run length and higher compression. This eventually translates to more query performance and space savings.</p>
<p>Fortunately, information theory provides us with an estimate of this, namely: <strong><a href="http://en.wikipedia.org/wiki/Mutual_information">mutual information</a></strong>. For two columns, it is defined as:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/07/image31.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/07/image_thumb31.png?w=335&#038;h=59" width="335" height="59" /></a></p>
<p><strong>p(x,y)</strong> is the empirical measured frequency of each column combination, divided by the total number of combinations of X and Y. We can extend the SQL statement above to this:</p>
<blockquote><p><font face="Consolas"><strong>SELECT</strong> X, Y         <br />, CAST(COUNT(*) AS FLOAT) / SUM(COUNT(*)) OVER (PARTITION BY NULL) pXY         <br /><strong>FROM</strong> Table         <br /><strong>GROUP BY</strong> X, Y</font></p>
</blockquote>
<p>And by joining up the calculated probabilities from the Entropy calculation we can find <strong>I(X;Y)</strong>. We are almost there, bear with me a little longer. The value <strong>I(X;Y)</strong> tells us something about how much information (again, measured in bits) the column share. Combined with H(X) we can now calculate the “information distance” between two columns. This is know as the Variation of Information and is denoted by <strong>d(X,Y)</strong>:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/07/image32.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/07/image_thumb32.png?w=329&#038;h=62" width="329" height="62" /></a></p>
<p>At this point, it should be clear that it is possible calculate a matrix like this:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/07/image33.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/07/image_thumb33.png?w=414&#038;h=345" width="414" height="345" /></a></p>
<p>&#160;</p>
<p>Think of this matrix as the information distance between each column, a map of the entropic landscape if you wish.</p>
<p style="padding-left:20px;padding-right:20px;">Side note: Unfortunately, this matrix is rather computer intensive to build. It takes O(n * c<sup>2</sup>) space and time to calculate I(X,Y) for all column combinations, with c being the column count in the table and n being the row count. It also requires some interesting, high speed data structures (may be subject of another blog) that I had to build myself because .NET 4 “concurrent” dictionary was not up to the task. I am currently looking for a way to estimate I(X,Y) instead of brute forcing the exact number. Ideas on how to approach this will be most appreciated.</p>
<p>&#160;</p>
<h3>Why Optimal is Hard</h3>
<p>With our d(X,Y) matrix, we may be able to find a path through the information landscape that minimises the amount of shared information of columns. Intuitively (?) this should increase column store compression by minimising the number of run lengths.</p>
<p>At this point, I have to make a few disclaimers. What I am about to propose is NOT an exact solution, in fact, it may even be worse than guessing in some cases. There are a couple of reasons for this</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/07/image34.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;float:left;padding-top:0;border-width:0;" title="image" border="0" alt="image" align="left" src="http://kejserbi.files.wordpress.com/2012/07/image_thumb34.png?w=98&#038;h=131" width="98" height="131" /></a>First of all, just because I know the mutual information I(A;B) and I(B;C) it does NOT follow that I know the total mutual information of the combination represented by I(A;B;C). For example, there could be an underlying structure in the data that is not detected by comparing column pairs. Such an underlying structure could send the following algorithm off into a walk goose chase.</p>
<p>Second, it may not even be true that lexicographical ordering of the column values leads to optimal compression. There are other ways to sort columns, for example in Gray Cycles.</p>
<p>Last, and most important: finding the &quot;shortest path through the information landscape” turns out to be an NP-hard problem. This has been proven here: &quot;<a href="http://arxiv.org/pdf/0909.1346.pdf">Reordering Columns for Small Indexes</a>”. The problem has even been baptised: RUNLENGTH.</p>
<p>What does it mean that a problem is <a href="http://en.wikipedia.org/wiki/NP-hard">NP-hard</a>? Consider for a moment our reordering of columns problem. There are&#160; <strong>c!</strong> ways to order the <strong>c</strong> columns in a table. This is a huge number ( c! = c * (c-1) * … * 1). We cannot explore them all in reasonable time, so we need an algorithm that finds the best one without looking at every combination. When a problem is NP-hard, it means that such an algorithm is known to either NOT exist, or if you can find it, you will win the Nobel price (because you would then have proven the great mystery of computer science, namely the <a href="http://en.wikipedia.org/wiki/P_versus_NP_problem">P = NP</a> problem).</p>
<h3>Can We Make a Good Guess?</h3>
<p>When a problem is NP-hard, our best bet is to come up with good heuristics. With the <strong>d(X,Y)</strong> matrix available, one particular heuristic lends itself well to easy implementation:</p>
<ul>
<li>Let S be an ordered set of columns </li>
<li>Pick a starting column c1 (the one with lowest entropy H(X) is often good) </li>
<li>Add c1 to S </li>
<li>From the columns not yet in S, find the one that has the smallest distance to any column in S. Add this to S </li>
<li>Repeat above until all columns are explored </li>
</ul>
<ul>Intuitively, we are greedily traversing the “landscape of information”, always adding the column that is closest to the part of the landscape we have already explored.</ul>
<h3>Early Test Results </h3>
<p>With the help of readers on this blog, I have managed to collect sample datasets from four retailers. Running my algorithm above, I can now quantify how well it does on these datasets. The following table lists the results:</p>
<p><a href="http://kejserbi.files.wordpress.com/2012/07/image35.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://kejserbi.files.wordpress.com/2012/07/image_thumb35.png?w=600&#038;h=138" width="600" height="138" /></a></p>
<p>A bit more detail about the algorithms here</p>
<p><strong>Cardinality</strong> sorts the columns either by lowest cardinality first (ASC) or highest cardinality first. Notice that this heuristic actually makes compression WORSE than random in some cases. Time complexity is (n * c) and interestingly, the space complexity can be done in O(c) if using HyperLogLog to estimate the cardinality.</p>
<p><strong>H(X) Entropy</strong> sorts the columns by either increasing or decreasing entropy. On the tested datasets, this algorithm fare somewhat better. It also had the advantage of being very fast to calculate: O(n * c)</p>
<p><strong>d(X,Y)</strong> <strong>Greedy</strong> is the algorithm described above (which is very slow to calculate: O(n * c<sup>2</sup>)</p>
<p><strong>Random </strong>is random ordering of the rows.</p>
<p>All data sizes have been measured using the SQL Server 2012 column store compression</p>
<h3>Introducing TableStat.exe</h3>
<p>To compute the test results above in reasonable runtime, I have written a little utility in .NET 4 called <strong>TableStat.Exe</strong>. </p>
<p>This utility can run on a sample and assuming there are not too many columns, crunch through tens of thousands of rows every second to calculate all the algorithms described above. When it is done running, it will output the SQL statements required to run the experiments to measure compression. Optionally, it will even run the experiment for you.</p>
<p>I would really like to collect more data on my candidate heuristics. If you have some real data that you would like to test on, I can get you a copy of <strong>TableStat.Exe</strong>. I don’t even need to see your data (the test can be run fully on your site), but I would ask that you share the compression results with me.</p>
<p>Send me an email, or comment on this blog, if this has your interest.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kejserbi.wordpress.com/800/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kejserbi.wordpress.com/800/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kejser.org&#038;blog=18866241&#038;post=800&#038;subd=kejserbi&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kejser.org/2012/07/27/what-is-the-best-sort-order-for-a-column-store/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/93e3150ebaf2321aef3dc4faee057861?s=96&#38;d=retro&#38;r=G" medium="image">
			<media:title type="html">schastar42</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/07/image_thumb28.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/07/image_thumb29.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/07/image_thumb30.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/07/image_thumb31.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/07/image_thumb32.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/07/image_thumb33.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/07/image_thumb34.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://kejserbi.files.wordpress.com/2012/07/image_thumb35.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
	</channel>
</rss>
