<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tag 'storage'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=storage&amp;orTags=0</link><description>Search results matching tag 'storage'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>File Layout Viewer vs. Drop Clustered Index</title><link>http://sqlblog.com/blogs/merrill_aldrich/archive/2013/06/03/file-layout-viewer-vs-drop-clustered-index.aspx</link><pubDate>Mon, 03 Jun 2013 06:41:53 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:49327</guid><dc:creator>merrillaldrich</dc:creator><description>&lt;p&gt;I had a very educational exchange the other day on Twitter (also known as “getting schooled”) by my SQL compatriots Argenis Fernandez (@DBArgenis) and Hugo Kornelis (@Hugo_Kornelis). A guy called Chris Switalski (@crswit) asked a really interesting question on #sqlhelp, which I proceeded to answer incorrectly, which led to a correction by my friends, which in turn took me back into the SQL File Layout Viewer, which quickly uncovered a bug there.&lt;/p&gt;  &lt;p&gt;So, learn from your friends on Twitter!&lt;/p&gt;  &lt;p&gt;Anyway, here’s the question, and corrected demo using an updated SQL File Layout Viewer build.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Question (paraphrasing): &lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;When you create a clustered index on a heap, the data from the heap is rewritten and ordered, and the upper levels of the index are added. If you &lt;strong&gt;drop&lt;/strong&gt; that clustered index, what happens? Does the set of leaf-level pages stay in place, and the index pages just get unlinked and deallocated? Or is the data rewritten again? Does it stay in the same logical or physical order, even though the ordering requirement is removed?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I had said that I imagine the data is rewritten in both cases, but that we could look and see to be sure. I was totally wrong – the leaf level of a clustered index is made of data pages, and a heap is made of data pages too, as Argenis pointed out. It turns out that, since they are not different structures down at that level, in order to drop a clustered index, the server will indeed just remove the upper levels of the index and leave all the leaf level data pages in place. Cool optimization! It turns out that my original release of the File Layout Viewer doesn’t always display this situation correctly, so I had to make some changes. This demo, though, I believe shows the behavior correctly.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;First, we make a test database and create a heap, and populate it with some dummy data:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;USE master
IF &lt;/span&gt;&lt;span style="color:gray;"&gt;EXISTS ( &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;1 &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;databases &lt;/span&gt;&lt;span style="color:blue;"&gt;WHERE &lt;/span&gt;name &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;'HeapTest' &lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;DROP DATABASE &lt;/span&gt;HeapTest&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;CREATE DATABASE &lt;/span&gt;HeapTest&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO

ALTER DATABASE &lt;/span&gt;HeapTest &lt;span style="color:blue;"&gt;SET RECOVERY SIMPLE&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO
ALTER DATABASE &lt;/span&gt;HeapTest &lt;span style="color:blue;"&gt;MODIFY FILE &lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;NAME &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'HeapTest'&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;SIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;102400KB &lt;span style="color:gray;"&gt;);
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO
ALTER DATABASE &lt;/span&gt;HeapTest &lt;span style="color:blue;"&gt;MODIFY FILE &lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;NAME &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'HeapTest_log'&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;SIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;10240KB &lt;span style="color:gray;"&gt;);
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO

USE &lt;/span&gt;HeapTest&lt;span style="color:gray;"&gt;;

&lt;/span&gt;&lt;span style="color:blue;"&gt;CREATE TABLE &lt;/span&gt;SampleData &lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;Data &lt;span style="color:blue;"&gt;uniqueidentifier DEFAULT &lt;/span&gt;&lt;span style="color:magenta;"&gt;NEWID&lt;/span&gt;&lt;span style="color:gray;"&gt;(), 
    &lt;/span&gt;Padding &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;100&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;DEFAULT &lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;&lt;span style="color:magenta;"&gt;CAST&lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;&lt;span style="color:magenta;"&gt;CHECKSUM&lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;&lt;span style="color:magenta;"&gt;NEWID&lt;/span&gt;&lt;span style="color:gray;"&gt;() ) &lt;/span&gt;&lt;span style="color:blue;"&gt;as CHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;100&lt;span style="color:gray;"&gt;) ) ) 
);
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO

INSERT &lt;/span&gt;SampleData &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO &lt;/span&gt;100000&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we run the File Layout Viewer, we see a nice, contiguous set of data pages (type 1) in teal:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/FLVDropClust01_7E43BA85.jpg"&gt;&lt;img title="FLVDropClust01" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="FLVDropClust01" src="http://sqlblog.com/blogs/merrill_aldrich/FLVDropClust01_thumb_158EBEF7.jpg" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we’ll add a NON clustered index, just so we can track what happens to that structure too:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;CREATE NONCLUSTERED INDEX &lt;/span&gt;Nonclust &lt;span style="color:blue;"&gt;ON &lt;/span&gt;SampleData &lt;span style="color:gray;"&gt;( &lt;/span&gt;Padding &lt;span style="color:gray;"&gt;);
&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;That shows up in the next part of the data file, in bright blue:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/FLVDropClust02_65F0A06A.jpg"&gt;&lt;img title="FLVDropClust02" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="FLVDropClust02" src="http://sqlblog.com/blogs/merrill_aldrich/FLVDropClust02_thumb_4490FACE.jpg" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now if we make a clustered index on the heap, it will have to be rewritten into another region of the file, so that it can be stored in the right logical order. We should expect it to “move” in the visualization down into the empty part of the file. The non clustered index will &lt;em&gt;also&lt;/em&gt; be rewritten, because it will switch from using physical row locations to point to data in the heap to using the clustering key to point to data in the new clustered index. Let’s see what it looks like:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;CREATE CLUSTERED INDEX &lt;/span&gt;Clust &lt;span style="color:blue;"&gt;ON &lt;/span&gt;SampleData &lt;span style="color:gray;"&gt;( &lt;/span&gt;Data &lt;span style="color:gray;"&gt;);
&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;The new clustered index and new version of the NON clustered index are both created in another region of the data file:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/FLVDropClust03_583DE462.jpg"&gt;&lt;img title="FLVDropClust03" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="FLVDropClust03" src="http://sqlblog.com/blogs/merrill_aldrich/FLVDropClust03_thumb_289FC5D6.jpg" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see, in lighter gray, the regions that were emptied where the two structures had been stored, and the two new structures now in the center of the graphic.&lt;/p&gt;

&lt;p&gt;Now for the part of the question I got wrong: what happens when we drop that clustered index?&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;DROP INDEX &lt;/span&gt;SampleData&lt;span style="color:gray;"&gt;.&lt;/span&gt;Clust&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is really neat: the leaf level of the clustered index (remember data pages are data pages) stays right where it is, and the upper level index pages are just deallocated/unlinked. &lt;/p&gt;

&lt;p&gt;The NON clustered index does have to be rebuilt yet again to change those clustered index keys out for row location pointers that point to the rows in the heap, so those pages do get rewritten into yet another region of the file:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/FLVDropClust04_6E444FF4.jpg"&gt;&lt;img title="FLVDropClust04" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="FLVDropClust04" src="http://sqlblog.com/blogs/merrill_aldrich/FLVDropClust04_thumb_45C56DE0.jpg" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, to summarize:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you add or remove a clustered index from a table, any NON clustered indexes always have to be rebuilt - and will be automatically - to exchange row pointers for clustering keys in the non clustered index itself. This generally takes care of itself, but it can be a performance issue, or cause longer running transactions or a large amount of logging.&lt;/p&gt;

&lt;p&gt;When you CREATE a clustered index on a heap, the data has to be rewritten to enforce the logical order of the index.&lt;/p&gt;

&lt;p&gt;When you DROP a clustered index, however, the server can keep all the leaf level pages in place and just strip away the index levels above.&lt;/p&gt;</description></item><item><title>Storage Performance</title><link>http://sqlblog.com/blogs/joe_chang/archive/2013/03/24/storage-performance.aspx</link><pubDate>Mon, 25 Mar 2013 03:52:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:48393</guid><dc:creator>jchang</dc:creator><description>&lt;p&gt;Storage has changed dramatically over the last three years driven by SSD developments.  
Most of the key components necessary for a powerful storage system are available
and the cost is highly favorable for direct placement of data files. 
Some additional infrastructure elements could greatly enhance the flexibility of storage systems with SSDs. There is still some discussion on whether SSD should interface directly to PCI-E 
or continue using the SAS/SATA interfaces originally designed for hard disks. 
New products coming this year include Express Bay, an ecosystem of connectors allowing 
both PCI-E and SAS/SATA to co-exist until a clear direction is established. 
Also expected in the coming year are PCI-E SSDs based on the NVM Express interface.
&lt;/p&gt;

&lt;h4&gt;System Level&lt;/h4&gt;
&lt;p&gt;
The Intel Xeon E5 processors, codename Sandy Bridge-EP, have 40 PCI-E gen 3 lanes&amp;nbsp;on each processor socket. Even though PCI-E gen 3 is 8GT/s, a change in the encoding means that the usable bandwidth is double that of PCI-E gen2 at 5GT/s. 
The net realizable bandwidth of a PCI-E gen 3 x8 slot is 6.4GB/s versus 3.2GB/s for gen 2.
&lt;/p&gt;

&lt;p&gt;
The unfortunate aspect is that the major server vendors all implement a mix of x16 and x4 slots, 
while the HBA vendors seem to be concentrating on products for PCI-E x8. 
Only Supermicro has a system with 10 &lt;strike&gt;8&lt;/strike&gt; PCI-E gen 3 x8 slots. 
Could a vendor put 2 HBA/RAID Controllers designed for x8 onto a single card for a x16 slot? 
Perhaps the new Express Bay form factor will have some means to use x16 slots?
&lt;/p&gt;

&lt;p&gt;&lt;img alt="Sandy Bridge EP 2-socket" src="http://www.qdpma.com/SystemArchitecture_files/SandyBridgeEP2f.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;
Another disappointment is that the 4-socket Xeon E5-46xx systems only connect half of the PCI-E lanes. This might be because the base system configuration is 2-socket populated. 
If a full set of slots are provided, there would no connection to half of the slots unless all four sockets are populated. But this is also an issue on the 2-socket systems if only 1 socket is populated.
&lt;/p&gt;
&lt;h4&gt;Direct-Attach&lt;/h4&gt;
&lt;p&gt;For the most part, I will discuss direct-attach storage configuration, 
as we can pick and choose among the latest components available. 
Technically, direct-attach with SAS can support  a 2-node cluster, 
but few system vendors promote this configuration. 
Dell sells the MD3200 as direct-attach storage supporting 4 hosts in a cluster (or not), 
but technically it is a SAN that just happens to use&amp;nbsp;SAS interfaces on both the front-end and back-end.
&lt;/p&gt;

&lt;p&gt;The objective in the baseline storage configuration below is to achieve 
very high IO bandwidth even in the low capacity configuration. 
Of course it will also have very high IOPS capability because the main elements are SSD. 
My recommended storage system has both SSD and HDD in each IO channel.
&lt;/p&gt;

&lt;p&gt;&lt;img width="600" height="300" alt="PCIe" src="http://www.qdpma.com/Storage_files/Config_2013b.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;
This intent is to place the main databases on SSD and use the HDD for backups and for restore verification. For an Inmon style data warehouse, the HDD might also be used for older data. 
The reason for having both SSD and HDD on each IO channel is to take advantage of simultaneous bi-directional IO. On a database backup, the IO systems reads from SSD, and simultaneously writes to HDD.
&lt;/p&gt;

&lt;p&gt;
4 RAID Controllers, 4GB/s per controller, 16GB/s total IO bandwidth&lt;br&gt;
4 Disk enclosures (yes, I am showing 8 enclosures in the diagram above)&lt;br&gt;
4 x 16 = 64 SSD&lt;br&gt;
4 x 8 = 32 (10K) HDD 
&lt;/p&gt;

&lt;p&gt;
The standard 2U enclosure has 24 x 15mm bays. My preference is for a 16 SSD and 8 HDD mix. 
With the small capacity 100GB SSD, there will be 1.6TB per enclosure and 6.4TB over 4 enclosures before RAID. In 7+1 RAID 5 groups, there will be 5.6TB net capacity, and 4.8TB in 3+1 RG across 4 units. The goal is 4GB/s per controller because the SAS infrastructure is still 6Gbps, 
supporting 2.2GB/s on each x4 port. With 16 SSDs per controller, each SSD needs to support 250MB/s. Most of the recent enterprise class SSDs are rated for well over 300MB/s per unit, 
allowing for a large degree of excess capability. 
Another option is to configure 12 SSDs per controller, expecting each SSD to support 333MB/s.
&lt;/p&gt;

&lt;p&gt;
The cost structure for the above is as follows:&lt;br&gt;
&amp;nbsp; RAID controller $1K &lt;br&gt;
&amp;nbsp; 2U Enclosure $3K &lt;br&gt;
&amp;nbsp; Intel SSD DC 3700 100GB SSD $235 x&amp;nbsp;16 = $3760, RAID 5 7+1: 1.6TB&lt;br&gt;
&amp;nbsp; Seagate Savvio 600GB 10K HDD $400
x 8 = $3200.&lt;/p&gt;

&lt;p&gt;
This works out to $11K per unit or $44K for the set of 4. 
The set of 16 x 100GB contributes $3760. For the 800GB SSD, the R5 7+1 capacity is 44.8TB at cost $148K. &lt;/p&gt;

&lt;p&gt;At maximum expansion of 4 enclosures per  RAID controller, capacity is 170TB at cost is $590K. Of course at this level, I would elect a system with more PCI-E slots for greater IO bandwidth. Another option is a RAID controller with 4 x4 SAS ports. 
Unfortunately none of these have 4 external ports.
&lt;/p&gt;

&lt;p&gt;
While the Intel SSD DC 3700 drew reviews for pioneering consistency of IO performance 
instead over peak performance, it is only available in SATA interface.
Micron &lt;strike&gt;Crucial&lt;/strike&gt; has &lt;strike&gt;announced&lt;/strike&gt; the P410m with similar specifications but with SAS interface. This is listed on the Micron website as in production, but probably only to&amp;nbsp;OEM customers.&amp;nbsp;There are other enterprise grade high endureance MLC SSDs with SAS interface as well.
&lt;/p&gt;

&lt;p&gt;
Note: I do not recommend anything less than 10K HDD even to support database backups. 
The 10K HDDs are not particularly expensive as direct-attach components ($400 for the 600GB model). Only SAN vendors sell $400 HDDs for $2K or more. 
&lt;/p&gt;
&lt;h4&gt;SAS 12Gbps Enclosures&lt;/h4&gt;
&lt;p&gt;
Disk enclosures supporting SAS at 12Gbps might become available as early as this year. 
Each of the 12Gbps SAS x4 uplink and down link ports would then support 4GB/s. 
The RAID controller (HBA) can support 6GB/s+ in a PCI-E gen 3 x8.  
The system with 4 RAID controllers could then deliver 24GB/s instead of 16GB/s. 
At 16 SSDs per controller, this would require 400MB/s per SSD. While SSDs are rated as high as 550MB/s, achieving the full aggregate bandwidth in an array&amp;nbsp;is not necessarily practical. So&amp;nbsp;400MB/s per SSD in an array is a more reasonable expectation. Also, enterprise SAS SSDs
many only be rated to 400MB/s.&lt;/p&gt;

&lt;p&gt;
We should not need 12Gbps SAS SSDs or HDDs in the near future (but 8 NAND channels&amp;nbsp;is a good match for a 1.1GB/s interface).&amp;nbsp;The internal wires in the enclosure connect through a SAS expander. 
The IO from each device bay can signal at 6Gbps, then uplink to the HBA at 12Gbps, 
assuming that packets are buffered on the expander.
&lt;/p&gt;

&lt;p&gt;&lt;img width="600" height="520" alt="PCIe" src="http://www.qdpma.com/Storage_files/Enclosure_b.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;
The standard 2U disk enclosure today supports 24 or 25 2.5in (SFF) bays, with 15mm thickness. 
This is the dimension of an enterprise class 10K or 15K HDD with up to 3 platters. 
The older full size notebook used a 9mm HDD supporting 2 platters. 
Thin notebooks used a 7mm HDD restricted to a single platter.  
There is no particular reason for an SSD to be more than 7mm. 
&lt;/p&gt;

&lt;p&gt;
 It would be better if the new 12Gbps SAS enclosures support more than 24 bays. 
My preference is  for 16 x 15mm and 16 x 7mm bays. The key&amp;nbsp;is to match the practically realizable aggregate bandwidth of SSDs to the uplink with some&amp;nbsp;degree of excess.
Personally, I would like to discard the SSD case to further reduce thickness.
&lt;/p&gt;

&lt;p&gt;&lt;img width="600" height="221" alt="PCIe" src="http://www.qdpma.com/Storage_files/Enclosure.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;
Another option is to employ the NGFF, perhaps a 1U stick, at 5mm or less. 
There could be 2 rows of 24 for SSD, and the 16 x 15mm bays.
&lt;/p&gt;

&lt;p&gt;
I believe that the all-SSD idea is misguided. SSDs are wonderful, but HDD still have an important role. One example is having the HDDs available for backup and restores. 
I want local HDD for backups because so very few people know how to configure for multiple parallel 10GbE network transmission, not to mention IO bandwidth on the backup system.
&lt;/p&gt;

&lt;p&gt;
A database backup that has not been actually verified to restore (with recovery) is a potentially useless backup. 
Having HDDs for backup and restore verification preserves the write endurance on the SSD. 
This allows the use of high-endurance MLC instead of SLC. 
In some cases, it might even be possible to use consumer grade MLC if and only if&amp;nbsp;the database organization maintenance strategy&amp;nbsp;is architected to minimize wear on the SSD.
&lt;/p&gt;
&lt;h4&gt;PCI-E SSD&lt;/h4&gt;
&lt;p&gt;
Some of the discussion on PCI-E versus SATA/SAS interface for the NAND/Flash controller 
incorrectly focuses on the bandwidth of a single 6Gbps lane versus 4 or 8 lanes on PCI-E. 
It is correct that PCI-E was designed to distribute traffic over multiple lanes 
and that hard drives were never expected to exceed to bandwidth of a single lane 
at the contemporary SATA/SAS signaling rate. 
The transmission delay across an extra silicon trip, 
from NAND controller with SATA interface to a SATA to PCI-E bridge chip, 
on the order of 50ns, 
is inconsequential compare this with the 25-50µsec access time of NAND.
&lt;/p&gt;

&lt;p&gt;
The more relevant matter is matching NAND bandwidth to the upstream bandwidth. 
All (or almost all?) the SATA interface flash controllers have 8 NAND channels. 
Back when SATA was 3Gbps and NAND was 40-50MB/s, 8 channel s to the 280MB/s net bandwidth of SATA 3G was a good match. 
About the time SATA moved to 6Gbps, NAND at 100-133MB/s became available so 8 channels was still a good choice.
&lt;/p&gt;

&lt;p&gt;&lt;img alt="PCIe" src="http://www.qdpma.com/Storage_files/SSD_SATA.png"&gt;&lt;br&gt;NAND is now at 200 and 333MB/s, while SATA is still 6Gpbs. 
The nature of silicon product cost structure is such that there is only minor cost reduction in building a 4 channel flash controller. 
The 8 channel controller only requires 256-pin package.
&lt;/p&gt;

&lt;p&gt;
The PCI-E flash controllers have been designed with 32 NAND channels. 
The IDT 32-channel controller has 1517 pins, 
which is not excessively difficult or expensive for a high-end server product. 
Note the Intel Xeon processors are 2011-pins. 
As noted earlier a PCI-E gen 3 x8 port supports 6.4GB/s. 
Over 32 channels, each channel needs to provide 200MB/s. 
The new 333MB/s NAND is probably a better fit to sustain the full PCI-E gen 3 x8 bandwidth after RAID (now RAIN because disks are replaced by NAND).
&lt;/p&gt;

&lt;p&gt;&lt;img alt="PCIe" src="http://www.qdpma.com/Storage_files/SSD_PCIE.png"&gt;
&lt;/p&gt;
&lt;p&gt;
Based on 64Gbit die, and 8 die per package, a package has 64GB raw capacity. The 32-channel PCI-E with 1 package per channel would have 2TB raw capacity (net capacity with 0.78 for over-provisioning and 0.875 for RAIN would be 1400GB) versus 512GB on an 8-channel SATA/SAS SSD.
The IDT document states capacity is 4TB raw for their 32-channel controllers, so perhaps it allows 2 packages per channel? The Micron datasheet mentions 32-channel and 64 placements.
&lt;/p&gt;

&lt;p&gt;
As is today, a PCI-E SSD can achieve maximum bandwidth at lower NAND capacity and in a more compact form factor than with SAS SSD.
On the other hand, SAS infrastructure provides flexible expansion. 
Capacity can be increased without replacing existing devices. 
Some systems support hot swap PCI-E slots. 
However the orientation of the connector in the system chassis makes this a complicated matter. 
The implications are that PCI-E slot SSDs are highly suitable for high density requirements with limited expansion needs. One database server example is tempdb on SSD.
&lt;/p&gt;
&lt;h4&gt;NVM Express&lt;/h4&gt;
&lt;p&gt;
The new generation of PCI-E SSDs may employ the NVMe interface standard. 
There is a standard driver for Windows and other operating systems, 
which will later be incorporated into to the OS distribution media 
allowing boot from an NVMe device, as with SATA devices today. 
This is mostly a client side feature.
&lt;/p&gt;

&lt;p&gt;
For the server side, the NVMe driver is designed for massive bandwidth and IOPS. 
There can be up to 64K queues, 64K commands (outstanding IO requests?). 
The driver is designed for IO to be both super-efficient in cpu-cycles 
and scalable on NUMA systems with very many processor cores. 
&lt;/p&gt;

&lt;p&gt;&lt;img width="600" height="228" alt="EMC VNX" src="http://www.qdpma.com/Storage_files/NVME_ScalableQueuingInterface.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;h4&gt;Express Bay&lt;/h4&gt;
&lt;p&gt;
To promote the growth of SSD without betting on which interface, 
the Express Bay standard defines a connector that can support both PCI-E and SATA or SAS. 
Some Dell servers today support PCI-E to SSDs in the 2.5in HDD form factor (SFF), 
but I am not sure if this is Express Bay. 
This form factor will allow PCI-E devices to hot-swapped with the same ease as SAS devices today.
&lt;/p&gt;

&lt;p&gt;&lt;img alt="PCIe" src="http://www.qdpma.com/Storage_files/ExpressBay.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;h4&gt;PCI-E Switches&lt;/h4&gt;
&lt;p&gt;
As mentioned earlier, the PCI-E slot arrangement in server systems does not facilitate hot-add,
even if it is supported.
Existing PCI-E SSDs also do not provide a mechanism for capacity expansion, 
aside from adding a card to an empty slot or replacing an existing card.
&lt;/p&gt;

&lt;p&gt;
Of course, there are PCI-E switches, just like the SAS expanders.
A 64 lane PCI-E switch could connect 5 x8 PCI-E devices over a x8 upstream link.
Other possibilities is a x16 link supporting 12.8GB/s to host with 4 ports for SSD,
or 8 x4 ports to SSD for finer grain expansion.
It may also be possible to support multiple hosts, as in a cluster storage arrangement?
&lt;/p&gt;

&lt;p&gt;&lt;img alt="PCIe" src="http://www.qdpma.com/Storage_files/PCI-E_switch.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;h4&gt;SAN Configuration&lt;/h4&gt;
&lt;p&gt;
Below is a representation of a typical configuration sold to customers by the SAN vendor. 
I am not joking in that it is common to find 2 ports FC or FCOE on each host. 
The most astounding case was a SAN with 240 x 15K disks and 2 single port FC HBAs in the server. 
Even though the storage system service processors had 4 FC port each (and the FC switches had 48-ports), only 1 on each SP was connected. 
Obviously the storage engineer understood single component and path failure fault-tolerant design. It was just too bad he built a fault-tolerant garden hose system when a fire hose was needed.
&lt;/p&gt;

&lt;p&gt;&lt;img width="465" height="558" alt="SAN_Configuration1c" src="http://www.qdpma.com/Storage_files/SAN_Configuration1c.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;
As I understand it, what happened was the SAN engineer asked how much space is needed for the databases accounting for growth, and then created one volume for it. 
The Windows OS does support multi-path IO. 
Originally the storage vendor provided the MPIO driver, but now it is managed by Microsoft. 
Apparently it was not considered that even with MPIO, all IO for a single volume has a primary path. The secondary path is only used when the primary is not available. 
&lt;/p&gt;
&lt;h4&gt;High-bandwidth SAN Configuration&lt;/h4&gt;
&lt;p&gt;
A proper SAN configuration for both OLTP and DW database servers is shown below. 
Traditionally, a transaction processing database generates small block&amp;nbsp;random IO (2KB in the old days, 8KB since SQL Server 7). As it&amp;nbsp;was difficult to get 10K IOPS (x8KB = 80MB/s),&amp;nbsp;it was thought that&amp;nbsp;IO bandwidth was not a requirement. 
This was 15 years ago. Apparently the SAN vendors read documents from this period, but not more recently, hence their tunnel vision on IOPS, ignoring bandwidth. &lt;/p&gt;

&lt;p&gt;For the last 10 or more years, people have been running large queries on the OLTP system. I have noticed report queries that saturate the storage&amp;nbsp;IO channels could essentially shutdown&amp;nbsp;transaction processing. This is because the report query generates asynchronous IO at high queue depth, while the transaction queries issue synchronous IO at queue depth 1.&amp;nbsp;And the report may escalate to a table lock (or it may use nolock).&amp;nbsp;Furthermore, it is desirable to be able to backup and restore the transaction database quickly. This means bandwidth. 
&lt;/p&gt;

&lt;p&gt;
Note that the system below shows 8Gbps FC, not 10Gbps FCOE. 
A single 10Gbps FCOE may have more bandwidth than a single 8Gbps FC port. 
But no serious storage system will have less than 4 or even 8 ports. 
Apparently FCOE currently does not scale well over multiple ports, due to the overhead of handling Ethernet packets? 
An Intel IDF 2012 topic mentions that this will be solved in the next generation.&lt;/p&gt;

&lt;p&gt;&lt;img width="428" height="635" alt="SAN_Configuration2e" src="http://www.qdpma.com/Storage_files/SAN_Configuration2e.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;
The above diagram shows 8 x 8Gbps FC ports between host and storage system.
Each 8Gbps FC port can support 700MB/s for a system IO bandwidth target of 5.6GB/s.
An OLTP system that handles&amp;nbsp;very high transaction volume may benefit from a dedicated HBA and  
FC ports for log traffic. This would allow the log HBA to be configured for low latency,
and the data HBA to be configured with interrupt moderation and high throughput.
&lt;/p&gt;

&lt;p&gt;
An alternate SAN configuration for SQL Server 2012 is shown below with local SSD for tempdb.
&lt;/p&gt;

&lt;p&gt;&lt;img width="485" height="633" alt="SAN_Configuration3b" src="http://www.qdpma.com/Storage_files/SAN_Configuration3b.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;
The write cache on a SAN must be mirrored for fault tolerance. 
There is very little detail on the bandwidth capability of the link between controllers 
(or SP) on SAN systems, beyond what can be deduced from the fact that the sustained write bandwidth is much lower than the read bandwidth.
So keeping tempdb off the SAN should preserve IO write bandwidth for traffic that
actually needs protection.
&lt;/p&gt;


&lt;p&gt;
The number of volumes for data and temp should be some multiple of 8.
It would be nice to have 1 volume for each FC path.
However we do need to consider how SQL Server place extents over multiple files.
This favors RAID groups of 4 disks.
&lt;/p&gt;
&lt;h4&gt;File Layout&lt;/h4&gt;
&lt;p&gt;
In a HDD storage system, 
the objective for bandwidth is to simultaneously issue large block IO
to all data disks across all IO channels.
A 256K block could be sufficiently large to generate 100MB/s per disk (400 IOPS, not random).
If this were issued at low queue depth (2?), 
then the storage system would not only generate high IO bandwidth
and still be perceptually responsive to other requests for small block IO.
&lt;/p&gt;

&lt;p&gt;
For small block random IO, it is only necessary to distribute IO over all hard disks with reasonable uniformity.
&lt;/p&gt;

&lt;p&gt;
The file layout strategy has two objectives. 
One is to not overwhelm any single IO channel.
In direct-attach, this is not a proper as the smallest pipe is x4 SAS for 2GB/s.
In a SAN, even using 8Gbps FC, this is a concern as 8Gb FC can support only 700-760MB/s.
Although 10Gb FCoE seems to have higher bandwidth, this may not scale with the number of channels
as well as straight FC.
The new Intel Xeon E5 (Sandy-Bridge EP) processors may be able to scale 10Gb FCoE 
with Data Direct IO (DDIO) - but this needs to be verified.
&lt;/p&gt;

&lt;p&gt;
The second is to ensure IO goes to every disk in the RAID Group (or volume).
By default, SQL Server allocates a single 64K extent from each file
before round-robin allocating from the next file.
This might be the reason that many SAN systems generate only 10MB/s per disk (150 IOPS at 64K),
along with no read-ahead.
&lt;/p&gt;

&lt;p&gt;&lt;img width="463" height="496" alt="FileLayout_1" src="http://www.qdpma.com/Storage_files/FileLayout_1.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;
The -E startup flag instructs SQL to allocate up to 4 consecutive extents
before proceeding to the next file.
See James Rowland-Jones 
&lt;a href="http://consultingblogs.emc.com/jamesrowlandjones/archive/2010/04/25/focus-on-fast-track-understanding-the-e-startup-parameter.aspx" target="blank"&gt;
Focus on Fast Track : Understanding the –E Startup Parameter&lt;/a&gt;
for more on this.
In a 4-disk RAID group with stripe-size 64K, a 256K IO to the file
would generate a 64K IO to each disk.
&lt;/p&gt;

&lt;p&gt;&lt;img width="463" height="496" alt="FileLayout_2" src="http://www.qdpma.com/Storage_files/FileLayout_2.png"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;
It would be necessary to rebuild indexes before this scheme takes effect.
Somewhere it was mentioned that it is important to build indexes with max degree of parallelism 
limited to either 4 or 8. It might be in the 
&lt;a href="http://msdn.microsoft.com/en-us/library/hh918452.aspx" target="blank"&gt;
Microsoft Fast Track Data Warehouse Reference Architecture&lt;/a&gt;.
Start with version 4 for SQL Server 2012, and work backwards?
&lt;/p&gt;

&lt;p&gt;
Trace Flag 1117 (-T1117) causes all files in a filegroup to grow together.
See
&lt;a href="http://blogs.technet.com/technet_blog_images/b/sql_server_sizing_ha_and_performance_hints/archive/2012/02/09/sql-server-2008-trace-flag-t-1117.aspx" target="blank"&gt;
SQL Server 2008 Trace Flag -T 1117&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
With SSD, the second may not be important as the SQL Server read-ahead strategy
(1024 pages?) should generate IO to all units.
On the hard disk, generate close-to-sequential IO was important.
On SSD, it is sufficient beneficial just to generate large block IO, with 64K being large.
&lt;/p&gt;
&lt;h4&gt;Summary&lt;/h4&gt;
&lt;p&gt;
The old concept of distributing IO over both devices and channels still apply.
The recent pricing of SSD is sufficiently low to warrant serious consideration ($2-3K/TB eMLC).
While there is more flexibility in SSD configuration, 
it is still necessary to validate performance characteristics
with real queries to an actual database. 
SQLIO or other synthetic tests are not sufficient.
If the SAN vendor advised in the configuration, 
then chances are IO bandwidth will be not be good.
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Addendum&lt;/strong&gt;&lt;br&gt;
If anyone thinks I am being unfair to or&amp;nbsp;overly critical of SAN vendors, do the following test.&lt;br&gt;
Find the biggest table in your database, excluding LOB fields.&lt;br&gt;
Run this:&lt;br&gt;
&lt;font color="#0000ff" face="Consolas"&gt;DBCC &lt;/font&gt;
&lt;font color="#008080" face="Consolas"&gt;DROPCLEANBUFFERS&lt;/font&gt;&lt;br&gt;
&lt;font color="#0000ff" face="Consolas"&gt;GO&lt;/font&gt;&lt;br&gt;
&lt;font color="#0000ff" face="Consolas"&gt;SET STATISTICS&lt;/font&gt;
&lt;font color="#0000ff" face="Consolas"&gt;IO ON&lt;/font&gt; &lt;br&gt;
&lt;font color="#0000ff" face="Consolas"&gt;SET STATISTICS&lt;/font&gt;
&lt;font color="#0000ff" face="Consolas"&gt;TIME ON&lt;/font&gt;&lt;br&gt;
&lt;font color="#0000ff" face="Consolas"&gt;GO&lt;/font&gt; &lt;br&gt;
&lt;font color="#0000ff" face="Consolas"&gt;SELECT&lt;/font&gt;
&lt;font color="#ff00ff" face="Consolas"&gt;COUNT&lt;/font&gt;&lt;font color="#808080" face="Consolas"&gt;(*)&lt;/font&gt;
&lt;font color="#0000ff" face="Consolas"&gt;FROM&lt;/font&gt;
&lt;font color="#008080" face="Consolas"&gt;TableA&lt;/font&gt;
&lt;font color="#0000ff" face="Consolas"&gt;WITH&lt;/font&gt;
&lt;font color="#808080" face="Consolas"&gt;(&lt;/font&gt;&lt;font color="#0000ff" face="Consolas"&gt;INDEX&lt;/font&gt;&lt;font color="#808080" face="Consolas"&gt;(&lt;/font&gt;&lt;font face="Consolas"&gt;0&lt;/font&gt;&lt;font color="#808080" face="Consolas"&gt;))&lt;/font&gt; &lt;br&gt;
&lt;font color="#0000ff" face="Consolas"&gt;GO&lt;/font&gt;
&lt;/p&gt;

&lt;p&gt;
Then compute 8 (KB/page) * (physical reads + read-ahead reads)/(elapsed time in ms)&lt;br&gt;Is this closer to 700 MB/s or 4GB/s? What did your SAN vendor tell you?&lt;/p&gt;

&lt;p&gt;I am also not fan of SSD caching or auto-tiering on critical databases, meaning the database that runs your business, that is managed by one or more full-time DBAs. In other applications, there may not be a way to segregate the placement of hot data differently from inactive data. In SQL Server, there are filegroups and partitioning. We have all the necessary means of isolating and placing hot data whereever we want it. SSD caching or auto-tiering will probably require SLC NAND. With active management using database controls, we should be able to use HET MLC or&amp;nbsp;even MLC.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;I stress the importance of analyzing the complete system and how it will be used instead of over-focusing on the components. There are criteria that might be of interest when there is only a single device or even single HBA. Today it is possible to over-configure the storage performance without unwarranted expense, and&amp;nbsp;this is best accomplished by watching the big picture.&lt;/p&gt;

&lt;p&gt;Adaptec reports that their Series 7 SAS RAID Controller&amp;nbsp;(72405 - PCI-E gen 3 x8 on the upstream side and 6 x4 SAS 6Gpbs) using the PMC&amp;nbsp;PM8015 controller can do&amp;nbsp;500K IOPS and 6.6GB/s.&lt;/p&gt;

&lt;p&gt;I will keep this topic up to date on &lt;a href="http://www.qdpma.com"&gt;www.qdpma.com&lt;/a&gt; 
&lt;a href="http://www.qdpma.com/Storage/Storage2013.html" target="blank"&gt;Storage 2013&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;related posts on storage:&lt;br&gt;
&lt;a href="http://sqlblog.com/blogs/joe_chang/archive/2010/10/18/io-queue-depth-strategy.aspx"&gt;io-queue-depth-strategy&lt;/a&gt; (2010-08)
&lt;br&gt;
&lt;a href="http://sqlblog.com/blogs/joe_chang/archive/2010/03/23/data-log-and-temp-file-placement.aspx"&gt;data-log-and-temp-file-placement&lt;/a&gt; (2010-03)
&lt;br&gt;
&lt;a href="http://sqlblog.com/blogs/joe_chang/archive/2008/09/04/io-cost-structure-preparing-for-ssd-arrays.aspx"&gt;io-cost-structure-preparing-for-ssd-arrays&lt;/a&gt; (2008-09)
&lt;br&gt;
&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; (2008-03)
&lt;/p&gt;

&lt;p&gt;
ps,&lt;br&gt;
If you are using SQL Server 2012 clustering on a SAN, 
I do suggest placing tempdb on local SSD, making use of the new 2012 feature 
that does not require tempdb to be on shared storage.
Keep in mind on the SAN, writes must be mirrored between two storage processors for fault recovery, and this is not a cheap thing to do.
We should plan redo whatever was using tempdb at the time.
&lt;/p&gt;</description></item><item><title>T-SQL Tuesday #040: Files, Filegroups and Visualizing Interleaved Objects</title><link>http://sqlblog.com/blogs/merrill_aldrich/archive/2013/03/12/t-sql-tuesday-040-files-filegroups-and-visualizing-interleaved-objects.aspx</link><pubDate>Tue, 12 Mar 2013 05:08:52 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:48197</guid><dc:creator>merrillaldrich</dc:creator><description>&lt;p&gt;Early in my career as a DBA, I have to admit I didn’t quite “get” what all the fuss was about with the multiple file and multiple filegroup capability in SQL Server. Over the years, though, as I learned more about partitioning, backup strategies for large databases and, most importantly, storage internals I’ve started to catch on. For today’s T-SQL Tuesday, I thought I would share an early lesson, using the newly released SQL File Layout Viewer utility available &lt;a href="http://sqlblog.com/blogs/merrill_aldrich/archive/2013/03/01/public-release-sql-server-file-layout-viewer.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.midnightdba.com/Jen/2013/03/invitation-to-t-sql-tuesday-040-file-and-filegroup-wisdom/"&gt;&lt;img title="tsql2sday" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;float:right;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="tsql2sday" align="right" src="http://sqlblog.com/blogs/merrill_aldrich/tsql2sday_1D86BA1E.jpg" width="150" height="150" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Adam Machanic started T-SQL Tuesday several years ago and it’s been a great way to motivate bloggers and readers to share ideas around a topic. This month’s even is hosted by &lt;a href="http://www.midnightdba.com/Jen/2013/03/invitation-to-t-sql-tuesday-040-file-and-filegroup-wisdom/"&gt;Jen McCown / MidnightDBA&lt;/a&gt;. An awesome idea, as ever.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;   &lt;p&gt;What I hope to illustrate today is a simple but vital concept about files and file groups: &lt;strong&gt;files&lt;/strong&gt;, on their own, use a &lt;em&gt;proportional fill algorithm&lt;/em&gt; in SQL Server and will receive new data from any object that needs more space. If an object needs additional storage, an allocation will be made in an empty area of whichever file has the most space available. Under the multi-file feature alone, there is no attempt whatsoever to separate objects in the database logically into different files. The result is that objects can appear to “round robin” through the files as more space is allocated – it’s not really a round-robin algorithm, but if the files are all about equally full, it looks similar.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Filegroups&lt;/strong&gt;, on the other hand, allow logically grouping objects in a way that specifically directs them into separate files, and so controls the physical layout of those objects on disk. Using filegroups it’s possible to direct an object into a file (or set of files) and physically separate it from the rest of the database.&lt;/p&gt;    &lt;p&gt;Because of this distinction, it’s been my experience that filegroups are far and away the more useful of the two features, and if I have a database that merits splitting up, I go straight for filegroups, with one physical file per group. (There are some edge case exceptions like TempDB allocation contention that are outside the scope of this post.)&lt;/p&gt;    &lt;h3&gt;Interleaving&lt;/h3&gt;    &lt;p&gt;There are a few reasons we’d want to physically separate objects, but, because it so clearly illustrates the difference, I want to show interleaving today. I made a demo database using the following script:&lt;/p&gt;    &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;USE &lt;/span&gt;[master]
&lt;span style="color:blue;"&gt;GO

&lt;/span&gt;&lt;span style="background:silver;"&gt;:setvar datapath &amp;quot;C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSQL\DATA&amp;quot;
:setvar logpath &amp;quot;C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSQL\DATA&amp;quot;

&lt;/span&gt;&lt;span style="color:blue;"&gt;CREATE DATABASE &lt;/span&gt;[VizDemo3] &lt;span style="color:blue;"&gt;ON  PRIMARY 
&lt;/span&gt;&lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;NAME &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'VizDemo3'&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:blue;"&gt;FILENAME &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'$(datapath)\VizDemo3.mdf' &lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;SIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;25600KB &lt;span style="color:gray;"&gt;, &lt;/span&gt;MAXSIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:blue;"&gt;UNLIMITED&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;FILEGROWTH &lt;span style="color:gray;"&gt;= &lt;/span&gt;51200KB 
&lt;span style="color:gray;"&gt;), 
&lt;/span&gt;&lt;span style="color:blue;"&gt;FILEGROUP &lt;/span&gt;[MultiFileFG] 
&lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;NAME &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'VizDemoMFGF1'&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:blue;"&gt;FILENAME &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'$(datapath)\VizDemoMFGF1.ndf' &lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;SIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;25600KB &lt;span style="color:gray;"&gt;, &lt;/span&gt;MAXSIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:blue;"&gt;UNLIMITED&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;FILEGROWTH &lt;span style="color:gray;"&gt;= &lt;/span&gt;51200KB 
&lt;span style="color:gray;"&gt;), 
( 
    &lt;/span&gt;NAME &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'VizDemoMFGF2'&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:blue;"&gt;FILENAME &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'$(datapath)\VizDemoMFGF2.ndf' &lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;SIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;25600KB &lt;span style="color:gray;"&gt;, &lt;/span&gt;MAXSIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:blue;"&gt;UNLIMITED&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;FILEGROWTH &lt;span style="color:gray;"&gt;= &lt;/span&gt;51200KB 
&lt;span style="color:gray;"&gt;), 
( 
    &lt;/span&gt;NAME &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'VizDemoMFGF3'&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:blue;"&gt;FILENAME &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'$(datapath)\VizDemoMFGF3.ndf' &lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;SIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;25600KB &lt;span style="color:gray;"&gt;, &lt;/span&gt;MAXSIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:blue;"&gt;UNLIMITED&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;FILEGROWTH &lt;span style="color:gray;"&gt;= &lt;/span&gt;51200KB 
&lt;span style="color:gray;"&gt;), 
&lt;/span&gt;&lt;span style="color:blue;"&gt;FILEGROUP &lt;/span&gt;[SingleFileFG1] 
&lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;NAME &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'VizDemoSFG1'&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:blue;"&gt;FILENAME &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'$(datapath)\VizDemoSFG1.ndf' &lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;SIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;25600KB &lt;span style="color:gray;"&gt;, &lt;/span&gt;MAXSIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:blue;"&gt;UNLIMITED&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;FILEGROWTH &lt;span style="color:gray;"&gt;= &lt;/span&gt;51200KB 
&lt;span style="color:gray;"&gt;), 
&lt;/span&gt;&lt;span style="color:blue;"&gt;FILEGROUP &lt;/span&gt;[SingleFileFG2] 
&lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;NAME &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'VizDemoSFG2'&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:blue;"&gt;FILENAME &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'$(datapath)\VizDemoSFG2.ndf' &lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;SIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;25600KB &lt;span style="color:gray;"&gt;, &lt;/span&gt;MAXSIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:blue;"&gt;UNLIMITED&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;FILEGROWTH &lt;span style="color:gray;"&gt;= &lt;/span&gt;51200KB 
&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;span style="color:magenta;"&gt;LOG &lt;/span&gt;&lt;span style="color:blue;"&gt;ON 
&lt;/span&gt;&lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;NAME &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'VizDemo3_log'&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:blue;"&gt;FILENAME &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N'$(logpath)\VizDemo3_log.ldf' &lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;SIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;10240KB &lt;span style="color:gray;"&gt;, &lt;/span&gt;MAXSIZE &lt;span style="color:gray;"&gt;= &lt;/span&gt;2048GB &lt;span style="color:gray;"&gt;, &lt;/span&gt;FILEGROWTH &lt;span style="color:gray;"&gt;= &lt;/span&gt;10240KB 
&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO

ALTER DATABASE &lt;/span&gt;[VizDemo3] &lt;span style="color:blue;"&gt;SET RECOVERY SIMPLE 
GO

USE &lt;/span&gt;VizDemo3
&lt;span style="color:blue;"&gt;GO

CREATE TABLE &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomers_on_Primary  &lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;id &lt;span style="color:blue;"&gt;int identity&lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;1&lt;span style="color:gray;"&gt;, &lt;/span&gt;1 &lt;span style="color:gray;"&gt;) NOT NULL &lt;/span&gt;&lt;span style="color:blue;"&gt;PRIMARY KEY CLUSTERED&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;buncha &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'A'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;big &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'B'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;vals &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'C'
&lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;[PRIMARY] &lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO

CREATE TABLE &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleOrders_on_Primary  &lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;id &lt;span style="color:blue;"&gt;int identity&lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;1&lt;span style="color:gray;"&gt;, &lt;/span&gt;1 &lt;span style="color:gray;"&gt;) NOT NULL &lt;/span&gt;&lt;span style="color:blue;"&gt;PRIMARY KEY CLUSTERED&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;buncha &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'A'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;big &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'B'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;vals &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'C'
&lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;[PRIMARY] &lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO

INSERT &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomers_on_Primary &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;INSERT &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleOrders_on_Primary &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO &lt;/span&gt;20000


&lt;span style="color:blue;"&gt;CREATE TABLE &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomers_on_Files  &lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;id &lt;span style="color:blue;"&gt;int identity&lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;1&lt;span style="color:gray;"&gt;, &lt;/span&gt;1 &lt;span style="color:gray;"&gt;) NOT NULL &lt;/span&gt;&lt;span style="color:blue;"&gt;PRIMARY KEY CLUSTERED&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;buncha &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'A'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;big &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'B'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;vals &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'C'
&lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;MultiFileFG &lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO

CREATE TABLE &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleOrders_on_Files  &lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;id &lt;span style="color:blue;"&gt;int identity&lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;1&lt;span style="color:gray;"&gt;, &lt;/span&gt;1 &lt;span style="color:gray;"&gt;) NOT NULL &lt;/span&gt;&lt;span style="color:blue;"&gt;PRIMARY KEY CLUSTERED&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;buncha &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'A'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;big &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'B'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;vals &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'C'
&lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;MultiFileFG &lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO

INSERT &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomers_on_Files &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;INSERT &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleOrders_on_Files &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO &lt;/span&gt;20000


&lt;span style="color:blue;"&gt;CREATE TABLE &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomers_on_FileGroups  &lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;id &lt;span style="color:blue;"&gt;int identity&lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;1&lt;span style="color:gray;"&gt;, &lt;/span&gt;1 &lt;span style="color:gray;"&gt;) NOT NULL &lt;/span&gt;&lt;span style="color:blue;"&gt;PRIMARY KEY CLUSTERED&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;buncha &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'A'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;big &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'B'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;vals &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'C'
&lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;SingleFileFG1 &lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO

CREATE TABLE &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleOrders_on_FileGroups  &lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;id &lt;span style="color:blue;"&gt;int identity&lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;1&lt;span style="color:gray;"&gt;, &lt;/span&gt;1 &lt;span style="color:gray;"&gt;) NOT NULL &lt;/span&gt;&lt;span style="color:blue;"&gt;PRIMARY KEY CLUSTERED&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;buncha &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'A'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;big &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'B'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;vals &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'C'
&lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;SingleFileFG2 &lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO

INSERT &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomers_on_FileGroups &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;INSERT &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleOrders_on_FileGroups &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO &lt;/span&gt;20000&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;This is a really simple example showing several possible file layouts, and what those do with the physical storage of the data. Starting from the top, note that the database create statement makes three different file setups:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Our old friend &lt;strong&gt;Primary&lt;/strong&gt; – one MDF file to rule them all!&lt;/li&gt;

  &lt;li&gt;A file group with three physical files: &lt;strong&gt;MultiFileFG&lt;/strong&gt;. These files will be populated with SQL Server’s proportional fill.&lt;/li&gt;

  &lt;li&gt;Two file groups with one physical file apiece: &lt;strong&gt;SingleFileFG1&lt;/strong&gt; and &lt;strong&gt;SingleFileFG2&lt;/strong&gt;. This allows the DBA to direct objects into specific files on disk.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Next I make some pairs of sample tables, and locate a pair in Primary, a pair in MultiFileFG, and a pair (one table each) in SingleFileFG1 and 2. The tables are each populated with 20,000 rows of sample data, arbitrarily called Customers and Orders.&lt;/p&gt;

&lt;p&gt;It’s important to note that the tables are filled with data in an alternating fashion – one table gets a row, then the other table gets a row – and that means that the allocations for space for those objects will also alternate. One table grows, then the other, then the first again.&lt;/p&gt;

&lt;p&gt;If the tables are in the same filegroup, even with separate physical files, the data will be interleaved. There will be a block of pages for one table allocated, then from the other table. Under default settings in SQL Server (not using the –E parameter, for example) the blocks of pages will each be a 64k extent of 8 data pages.&lt;/p&gt;

&lt;p&gt;So, let’s have a look at what happens inside the files, and see if it supports this logic.&lt;/p&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h3&gt;One File&lt;/h3&gt;

&lt;h3&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/InterleaveScreenCap1_6B22E69E.png"&gt;&lt;img title="InterleaveScreenCap1" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="InterleaveScreenCap1" src="http://sqlblog.com/blogs/merrill_aldrich/InterleaveScreenCap1_thumb_7C271481.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;My goodness it does! But you probably suspected that, as I’m the guy writing this post.&lt;/p&gt;

&lt;p&gt;First let’s look at the blue area – the stack-of-bricks looking light blue and purple region is the Primary filegroup / MDF file. What we are seeing is the alternating, interleaved extents from the two tables, one in blue and one in lavender/purple. This isn’t terrible, but there are two things worth noting:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;There’s a decent amount of fragmentation. Not harmful, necessarily, but these two tables definitely are not contiguous. If we have an application that wants to do a lot of scans, and we have spinning media, we might have some performance degradation. Read-ahead probably doesn’t work. This might not be ideal for a data warehouse.&lt;/li&gt;

  &lt;li&gt;If we re-index one of those objects the other one will remain full of “holes.” We could re-index both, but it might take a few passes before this interleaving works itself out.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I want to emphasize here that this isn’t necessarily a terrible situation, but it’s illuminating as far as how the data is physically written out.&lt;/p&gt;

&lt;h3&gt;Three Files in a Group&lt;/h3&gt;

&lt;p&gt;The next reasonable question to ask is whether making multiple files, alone, might solve this issue. So the next section of the visualizer, scrolling down a bit, shows the one filegroup/multiple file scenario from the demo. This is filegroup &lt;strong&gt;MultiFileFG&lt;/strong&gt;, shown in alternating pink and purple:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/InterleaveScreenCap2_6905E7D5.png"&gt;&lt;img title="InterleaveScreenCap2" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="InterleaveScreenCap2" src="http://sqlblog.com/blogs/merrill_aldrich/InterleaveScreenCap2_thumb_533BFF78.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice, we got three files, but the two tables we map into them are still interleaved, now across all three files. (Each file in the visualizer has a signature of orange-gray-orage system pages right at the beginning.)&lt;/p&gt;

&lt;p&gt;This pattern is because of the proportional fill applied to the physical files inside one filegroup. An extent is allocated for an object from one file, then the next file has the most available space, so the next file used for the next extent, and so on. This means our tables are still cut up into 8-page extents spread across the physical media.&lt;/p&gt;

&lt;h3&gt;Two Groups with One File Each&lt;/h3&gt;

&lt;p&gt;The last section of the demo writes each table into a separate filegroup, where each filegroup is backed by a single physical file. The results here are represented by the solid pink area in the graphic:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/InterleaveScreenCap3_2E3E3EFF.png"&gt;&lt;img title="InterleaveScreenCap3" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="InterleaveScreenCap3" src="http://sqlblog.com/blogs/merrill_aldrich/InterleaveScreenCap3_thumb_31DC59DC.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, the alternating inserts in the script don’t result in alternating allocations inside the files, because one table is specifically isolated to one filegroup and the other table to the other. In this case, the data in the files is practically contiguous.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Does this mean you should go out and make 1,000 file groups, one for every table or index? Please don’t! There’s a balance when planning files and filegroups between manageability, imagined performance impact of fragmentation (or real), complexity, and many other factors. SQL Server actually does a fine job, on smaller databases, working with one or a handful of files. But if you are planning a larger warehouse project, or you find the hardware you have struggles with the volume of data you need to manage, or you are looking at partitioning, then understanding how these storage internals behave, along with many other design considerations, will help.&lt;/p&gt;</description></item><item><title>Public Release, SQL Server File Layout Viewer</title><link>http://sqlblog.com/blogs/merrill_aldrich/archive/2013/03/01/public-release-sql-server-file-layout-viewer.aspx</link><pubDate>Fri, 01 Mar 2013 21:36:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:47991</guid><dc:creator>merrillaldrich</dc:creator><description>&lt;h2&gt;Version 1.0 is Now Available!&lt;/h2&gt;  &lt;p&gt;I’ve been working off and on, as my real job permits, on this visualization tool for SQL Server data files. This is an educational or exploratory tool where you can more readily &lt;i&gt;see&lt;/i&gt; how the individual data pages in MDF/NDF files are organized, where your tables and indexes live, what effect operations like index rebuild or index reorganize have on the physical layout of the data pages.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/FileLayoutViewerR1_6399E49C.png"&gt;&lt;img title="FileLayoutViewerR1" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="FileLayoutViewerR1" width="1028" height="494" src="http://sqlblog.com/blogs/merrill_aldrich/FileLayoutViewerR1_thumb_228B6538.png"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The viewer will scan a whole database, using only SQL and DBCC commands, and will render a color-coded representation of all the data pages represented in colored bands. Each partition of each index or heap in the database is assigned a color, so that you can see where all the bits and pieces of an object are located in the files. Above the colored bands there are grayscale or white pixels that show the page type in SQL Server (most are white, which are data pages. Unused/empty regions of the file show as gray). In the image above, for example, all the bright green areas are one index, all the purple areas are one index, and so on.&lt;/p&gt;  &lt;p&gt;There is mouse-over functionality. If you move the mouse cursor over the graph, then details about each page populate the text fields at right, including the object and index the page belongs to, the page type, whether the page represents a fragment, where the previous and next pages are for the same object, etc.&lt;/p&gt;  &lt;h2&gt;Why?&lt;/h2&gt;  &lt;p&gt;Why create something like this? I am a visual person, and I have a theory that many issues we have in computing come down to not being able to see what’s going on. This is especially true as we learn about unfamiliar technology – we have to develop a mental model of structures like B-trees or linked lists or files in order to understand what’s happening. I hope this tool, combined with other knowledge, will help people form an accurate understanding of how data file internals work in SQL Server, faster than working purely in the abstract with tools like DBCC Page or DBCC Ind.&lt;/p&gt;  &lt;h2&gt;Instructions&lt;/h2&gt;  &lt;ol&gt;   &lt;li&gt;Download the tool and unzip it. The package includes both an executable and the source code. If you don’t want the source, the .exe file is a standalone program and will run all on its own, so you are welcome to discard the source folder.&lt;/li&gt;    &lt;li&gt;Validate you have the required prerequisites from the Prereq’s section below.&lt;/li&gt;    &lt;li&gt;Locate a non-production/test database to analyze. The database can be local or on a remote server. I suggest something of a reasonable size, because scanning a really huge data set can take quite a long time.&lt;/li&gt;    &lt;li&gt;Run SQLFileLayoutViewer.exe and select a database to scan. If the database is on a remote server, type the SQL Server name/instance name into the dialog.&lt;/li&gt;    &lt;li&gt;Click Analyze.&lt;/li&gt;    &lt;li&gt;Examine the resulting graph, and mouse over it with the cursor to view detailed information about each page.&lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;Disclaimer&lt;/h2&gt;  &lt;p&gt;This is a freeware tool provided for your fun, education and entertainment. However, there is no warranty of any kind and you use it at your sole risk. The tool is free but offered under the GNU General Public License 3. If successful, and people are interested, I’ll move this work to some sort of open source project.&lt;/p&gt;  &lt;h2&gt;Prerequisites&lt;/h2&gt;  &lt;p&gt;The app requires .NET Framework 4.0 and the SQL Server management tools. I’ve tested it on Windows 7, Windows Server 2008 R2 and Windows 8. It can be run against a database on a local or remote SQL instance. I believe it will work on any database in SQL Server 2005 or later, but have not tested every possible scenario.&lt;/p&gt;  &lt;h2&gt;Risks?&lt;/h2&gt;  &lt;p&gt;I believe this tool to be relatively risk free, but I would avoid running it against live production data. The tool’s data collection is simple: it will issue a few system table selects to get things like object names, and then it will execute a DBCC PAGE statement against every page in the database. All other processing after that is done locally in the application itself. It does not modify the database.&lt;/p&gt;  &lt;h2&gt;Bugs?&lt;/h2&gt;  &lt;p&gt;I would love to hear about bugs you come across, or additional features you think would be valuable. Please contact me through this site. Note that I am a DBA first, and an amateur .NET developer a distant second, so please be gentle.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;</description></item><item><title>Visualizing Data File Layout III</title><link>http://sqlblog.com/blogs/merrill_aldrich/archive/2013/01/29/visualizing-data-file-layout-iii.aspx</link><pubDate>Tue, 29 Jan 2013 05:45:50 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:47372</guid><dc:creator>merrillaldrich</dc:creator><description>&lt;p&gt;This is part three of a blog series illustrating a method to render the file structure of a SQL Server database into a graphic visualization.&lt;/p&gt;  &lt;p&gt;Previous Installments:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/archive/2013/01/22/visualizing-data-file-layout-i.aspx"&gt;Part 1&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/archive/2013/01/23/visualizing-data-file-layout-ii.aspx"&gt;Part 2&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Those that have been reading this series might be be thinking, “Is he going to go there?” Well, the answer is “Yes.” This is the &lt;strong&gt;GUID clustered index post&lt;/strong&gt; that had to be. It’s inevitable with this tool.&lt;/p&gt;  &lt;p&gt;If you follow SQL Server at all, you are probably aware of the &lt;a href="http://www.sqlskills.com/blogs/kimberly/guids-as-primary-keys-andor-the-clustering-key/"&gt;long-standing&lt;/a&gt; &lt;a href="http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html"&gt;debate&lt;/a&gt; about whether it is wise, desirable, smart, useful, or what have you, to identify rows using GUIDs. I won’t take a position on that, but I will show here, I hope objectively, a few things that the visualizer shows about file layout vs. distributed inserts, distributed inserts being one of the main challenges around using GUIDs as clustering keys. Just to recap the argument very, very briefly:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;GUID keys can be generated at the client, which saves a round-trip to the database server to create a collection of related rows.&lt;/p&gt;  &lt;p&gt;GUID keys can make certain architectures like sharding, or peer to peer replication, or merging multiple source databases, simpler.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Disadvantages&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;GUID keys are wider, therefore they take more space in memory and on disk. The additional space is multiplied by their presence in both clustered and non-clustered indexes if they are a clustering key.&lt;/p&gt;  &lt;p&gt;GUID keys don’t only take more space in RAM and on disk because of their width. They also cause &lt;em&gt;distributed inserts&lt;/em&gt; into the clustered index – that is, new rows are added to any and all pages in the index. Each time a row has to be added, the target page must be read into memory, and at a checkpoint, the &lt;em&gt;whole&lt;/em&gt; changed page (both existing and new rows) must be written to disk. This has two effects: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The amount of RAM and disk IO required for inserts is probably much higher, as pages with &lt;em&gt;existing&lt;/em&gt; data must come into cache, get changed, and then be written back out again. Essentially, large parts of the table have to be &lt;em&gt;rewritten&lt;/em&gt; to disk to append rows to pages that have data already.&lt;/li&gt;    &lt;li&gt;The pages that store the index will individually fill up, and have to split such that half the existing rows are written back out to the “old” page and half written out to a “new” page in a different location on disk. This causes the pages to be less full, the same number of rows to require more space on disk and in RAM, and the resulting index to be massively fragmented on disk.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I am not writing to argue these points, which have I think been established by both sides of the debate, only to see if the visualizer shows these effects clearly. Most of the argument isn’t actually about these facts (they are all true, as far as I know) but rather which are more important, and I think that is the main source of debate on the issue.&lt;/p&gt;  &lt;h2&gt;Visual Example of Distributed Inserts&lt;/h2&gt;  &lt;p&gt;It’s very easy to create an example of this with a small sample database. I created one called “VizDemo2.” VizDemo2 has a slightly modified structure to illustrate what’s going on here – I need two tables that are stored separately on disk, so that they cannot interfere with one another. The simplest way to do that is with a couple of file groups containing one file each. So here’s the structure:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I created the database with a 50MB, single file, Primary file group&lt;/li&gt;    &lt;li&gt;I added a file group FG1 with one 75MB file&lt;/li&gt;    &lt;li&gt;I added a second file group FG2 with one 75MB file&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;When the database is empty, the visualizer shows only the system pages at the start of each file, as shown here:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo2_01_5BB678D6.png"&gt;&lt;img title="VizDemo2_01" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="VizDemo2_01" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo2_01_thumb_18DA345C.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;To that database I added two sample tables identical in structure but with different clustering keys:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;USE &lt;/span&gt;VizDemo2
&lt;span style="color:blue;"&gt;GO

CREATE TABLE &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomersInt  &lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;id &lt;span style="color:blue;"&gt;int identity&lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;1&lt;span style="color:gray;"&gt;, &lt;/span&gt;1 &lt;span style="color:gray;"&gt;) NOT NULL &lt;/span&gt;&lt;span style="color:blue;"&gt;PRIMARY KEY CLUSTERED&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;buncha &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'A'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;big &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'B'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;vals &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'C'
&lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;[FG1]&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO&lt;/span&gt;&lt;span style="color:blue;"&gt;
CREATE TABLE &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomersGuid  &lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;id &lt;span style="color:blue;"&gt;uniqueidentifier &lt;/span&gt;&lt;span style="color:gray;"&gt;NOT NULL &lt;/span&gt;&lt;span style="color:blue;"&gt;PRIMARY KEY CLUSTERED DEFAULT &lt;/span&gt;&lt;span style="color:magenta;"&gt;NEWID&lt;/span&gt;&lt;span style="color:gray;"&gt;(), 
    &lt;/span&gt;buncha &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'A'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;big &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'B'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;vals &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'C'
&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;[FG2]&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;I’ll populate the two tables and we can see what the file layout looks like afterward:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;INSERT &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomersInt &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;INSERT &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomersGuid &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO &lt;/span&gt;20000&lt;/pre&gt;


&lt;h2&gt;Compare&lt;/h2&gt;

&lt;p&gt;After inserts, the resulting graphic does show some facts we know to be true:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo2_02_6193AD20.png"&gt;&lt;img title="VizDemo2_02" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="VizDemo2_02" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo2_02_thumb_7A25DB21.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, the data in the integer-clustered index takes about eight bands of the diagram, while storing the same data in a GUID clustered index has required about twelve bands of data pages. The database itself supports that impression with space allocation – it reports these figures:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo2_03_50B199E1.png"&gt;&lt;img title="VizDemo2_03" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="VizDemo2_03" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo2_03_thumb_49262A74.png" width="737" height="75" /&gt;&lt;/a&gt;&lt;/p&gt;





&lt;p&gt;Part of the extra space required is the width of the key, but part of it is the empty space on each page resulting from page splits. If a page that needs a new row is too full, then half the rows from that page are moved to a net-new page, half left in place, and the new row added to one or the other of the resulting pages. Afterward, they are often both partly empty.&lt;/p&gt;

&lt;p&gt;Second, the whole graphic in the GUID clustered index area is a dark blue that the visualizer uses to show fragmentation – in fact, the object is almost perfectly fragmented, with practically no contiguous pages at all. The sequence of pages in the leaf level of the index is still a linked list, as always, but it it is physically stored in essentially random order on disk.&lt;/p&gt;

&lt;h2&gt;Does Re-Indexing Help?&lt;/h2&gt;

&lt;p&gt;The next question is whether we can combat these problems by doing huge amounts of index maintenance – if we rewrite the GUID index, will that make it take less space, or make it more efficient? The answer is, “well, sort of, temporarily.”&lt;/p&gt;

&lt;p&gt;First, re-indexing will put the table in “GUID” order. Whether that really helps or not is debatable, perhaps. It would enable read-ahead for the index, which is otherwise clobbered by the fragmentation. Having the table in “GUID” order might or might not be of any help to performance. Second, re-indexing will make the pages denser, or less dense, depending on the fill factor applied. For the sake of demonstration, let’s re-index with the default fill factor, because I think that happens a lot out in the world, and it may tell us something:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;ALTER INDEX &lt;/span&gt;&lt;span style="color:gray;"&gt;ALL &lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomersGuid &lt;span style="color:blue;"&gt;REBUILD&lt;/span&gt;&lt;span style="color:gray;"&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;After re-indexing, this is a view just of the second file group with the GUID clustered table (note that I scrolled down in the display):&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo2_04_3266E2EB.png"&gt;&lt;img title="VizDemo2_04" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="VizDemo2_04" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo2_04_thumb_1B3B686D.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The arrow shows where the data was moved from the old data pages into a new region of the file. And, sure enough, it’s not fragmented (note the lighter color) and it takes less space in the file.&lt;/p&gt;

&lt;p&gt;That might sound good, but if this is a real database, inserts probably will continue. In the int clustered case, as we know, new data will be appended to the end of the page sequence, but in this case, new data will have to be inserted into most of the existing pages on disk. Those are all full now, and will have to be split 50/50 to create new pages for the new data, both the old and new pages will have to be written out, and the new pages by definition can’t be in index order with the existing pages.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;INSERT &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomersGuid &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO &lt;/span&gt;20000&lt;/pre&gt;


&lt;p&gt;What we get after more rows are added to the table is what a layperson might call a “hot mess:”&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo2_05_1D0BBE34.png"&gt;&lt;img title="VizDemo2_05" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="VizDemo2_05" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo2_05_thumb_7A4A8676.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here everything is fragmented – back to that dark blue – even the pages we just re-indexed a moment ago, because they all split. The table has &lt;em&gt;more than&lt;/em&gt; doubled in size, even though we just doubled the number of rows, because the individual pages contain less data.&lt;/p&gt;

&lt;p&gt;Would appropriate fill factor be a workaround? In some measure, yes, but it really only combats the issue. The write activity on the table, even with a low fill factor, will still be higher as more existing pages have to be flushed at checkpoints. The pages will still be less dense, and therefore take up more space on disk and in cache. In short – maybe helpful but no silver bullet.&lt;/p&gt;

&lt;p&gt;What about Sequential GUIDs? Here I will venture my opinion. Sequential GUIDs have never made sense to me. They solve one part of this problem – the distributed insert part – but &lt;em&gt;at the expense of the very things GUIDs might be good for&lt;/em&gt;, namely not demanding a visit to the database to generate an identifier. If you have to come to the database, you already lost this whole argument. Use an integer and solve the rest of the problem at the same time. I can only see it as a sort of band-aid for existing systems that could not be refactored, but, like a bad SUV that combines the worst properties of a car and a truck, it feels like a really poor compromise to me.&lt;/p&gt;

&lt;p&gt;I hope this helps to illustrate some of the physical database design challenges that surround the use of GUID cluster keys. In the next installment I’m planning to demonstrate the interleaving of objects, which is one argument for multiple file groups.&lt;/p&gt;</description></item><item><title>Visualizing Data File Layout II</title><link>http://sqlblog.com/blogs/merrill_aldrich/archive/2013/01/23/visualizing-data-file-layout-ii.aspx</link><pubDate>Wed, 23 Jan 2013 23:40:02 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:47268</guid><dc:creator>merrillaldrich</dc:creator><description>&lt;p&gt;Part 2 of a blog series visually demonstrating the layout of objects on data pages in SQL Server&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/archive/2013/01/22/visualizing-data-file-layout-i.aspx"&gt;Part 1&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In Part 1 of this series, I introduced a little demo app that renders the layout of pages in SQL Server files by object. Today I’ll put that app through its paces to show, in vivid color (well, teal, anyway) the destructive power of the famous&lt;strong&gt; Re-Index Then Shrink&lt;/strong&gt; anti-pattern for index maintenance.&lt;/p&gt;  &lt;p&gt;This one is very easy to demo, so let’s go!&lt;/p&gt;  &lt;p&gt;First, I created a demo database &lt;strong&gt;VizDemo1&lt;/strong&gt;, with a single 200 MB data file. Into that database I placed a canonical table – highly simplified for this example – clustered on an ever-increasing integer, using identity():&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;USE &lt;/span&gt;VizDemo1
&lt;span style="color:blue;"&gt;GO

CREATE TABLE &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomers  &lt;span style="color:gray;"&gt;( 
    &lt;/span&gt;id &lt;span style="color:blue;"&gt;int identity&lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;/span&gt;1&lt;span style="color:gray;"&gt;, &lt;/span&gt;1 &lt;span style="color:gray;"&gt;) NOT NULL &lt;/span&gt;&lt;span style="color:blue;"&gt;PRIMARY KEY CLUSTERED&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;buncha &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'A'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;big &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'B'&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
    &lt;/span&gt;vals &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;default &lt;/span&gt;&lt;span style="color:red;"&gt;'C'
&lt;/span&gt;&lt;span style="color:gray;"&gt;);
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO
&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Then we populate that table with some dummy data:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;INSERT &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomers &lt;span style="color:blue;"&gt;DEFAULT VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;;

&lt;/span&gt;&lt;span style="color:blue;"&gt;GO &lt;/span&gt;40000&lt;/pre&gt;


&lt;p&gt;And finally, fire up the little visualizer app and process the database:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_01_4683F23D.png"&gt;&lt;img title="VizDemo1_01" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;float:none;padding-top:0px;padding-left:0px;margin-left:auto;border-left:0px;display:block;padding-right:0px;margin-right:auto;" border="0" alt="VizDemo1_01" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_01_thumb_53EA0543.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The small color bands at the top left corner of the image are the system tables and such that are in every “empty” database to make it run. The blue/green/teal area is the new table we created and populated with sample data, and the gray area represents empty regions in the file.&lt;/p&gt;

&lt;p&gt;As expected, the table started writing into the first available space, and, because the cluster key is increasing, pages were allocated to the end of the page sequence in order, and we end up with a crazy-perfect, contiguous linked list on disk.&lt;/p&gt;

&lt;p&gt;You can see small darker bars at intervals within the table – most of the pages in the index are “type 1” pages, which are the leaf-level/rows in the clustered index. Those bars are “type 2” index pages that have the upper level(s) of the index. The reason they are darker is that those are a disruption in the leaf level linked list, and the app shades such disruptions as a way to see fragmentation. The list has to “hop over” those pages and then continue on the other side. It’s technically fragmentation, but at this point not harmful at all – but remember that darker color that shows a break in the page order.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A side note: in the midst of the gray area you can see one orange line (and another in the sea of teal). Those are “type 11” PFS pages, which happen on a fixed interval in every file. I don’t think they ever move – they track file allocation and free space metadata. They are like rocks in the stream…&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, what happens if we re-index this bad boy? Well, a re-index operation has to write all the pages for the object into new, blank pages in the file, and then abandon the old pages. I run:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:green;"&gt;-- This &amp;quot;moves&amp;quot; all the data toward the end of the file, into free areas
&lt;/span&gt;&lt;span style="color:blue;"&gt;ALTER INDEX &lt;/span&gt;&lt;span style="color:gray;"&gt;ALL &lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomers &lt;span style="color:blue;"&gt;REBUILD&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Then re-analyze the file. As expected, the table has “moved” toward the end of the file, and left free space toward the beginning. It’s still not fragmented, because we had enough room, and it was written in order into that new area by the rebuild:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_02_61501849.png"&gt;&lt;img title="VizDemo1_02" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;float:none;padding-top:0px;padding-left:0px;margin-left:auto;border-left:0px;display:block;padding-right:0px;margin-right:auto;" border="0" alt="VizDemo1_02" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_02_thumb_3EFB1381.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see the gray area near the top is all the “abandoned” pages where the index was, and the data has all moved down into the free area. Ah, but that seems wasteful to some people, am I right? All that empty space – the file could be smaller!&lt;/p&gt;

&lt;p&gt;Let’s see the damage that Shrink File does. Imagine that I do this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;DBCC &lt;/span&gt;SHRINKFILE &lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:red;"&gt;N'VizDemo1' &lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;70&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO
&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;First, before we shrink, let’s just scroll down and look at the end of the file:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_03_4E9DAF43.png"&gt;&lt;img title="VizDemo1_03" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;float:none;padding-top:0px;padding-left:0px;margin-left:auto;border-left:0px;display:block;padding-right:0px;margin-right:auto;" border="0" alt="VizDemo1_03" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_03_thumb_10A41E85.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have two conditions – the gray part of the file is sort of OK to shrink. There’s just a lone PFS page out there, and removing that does no harm. But once we get into that blue area, the data has to be moved back up into the beginning of the file. Here’s where the problem lies, as I learned from Mr. Paul Randal – the shrink routine will move a page at a time back into that free space, starting from the end, going backward. That makes the pages land in approximately &lt;em&gt;reverse order&lt;/em&gt; from the correct index order. Perfect fragmentation. Let’s see if this tool proves him right. Shrink, then re-analyze:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_04_595D9749.png"&gt;&lt;img title="VizDemo1_04" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;float:none;padding-top:0px;padding-left:0px;margin-left:auto;border-left:0px;display:block;padding-right:0px;margin-right:auto;" border="0" alt="VizDemo1_04" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_04_thumb_500462C6.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yep, it’s not immediately apparent, perhaps, but that teal color is a darker shade that indicates every page is a fragment boundary in most of the index – perfect fragmentation! Here’s a better view:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_04a_51D4B88D.png"&gt;&lt;img title="VizDemo1_04a" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;float:none;padding-top:0px;padding-left:0px;margin-left:auto;border-left:0px;display:block;padding-right:0px;margin-right:auto;" border="0" alt="VizDemo1_04a" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_04a_thumb_665A080B.png" width="408" height="284" /&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;So, how can we clean that up? Well, with a rebuild. But … we need that bigger file. In fact, practically any database in production needs this overhead of available space to be able to perform index maintenance. It’s not “wasted” space at all.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;ALTER INDEX &lt;/span&gt;&lt;span style="color:gray;"&gt;ALL &lt;/span&gt;&lt;span style="color:blue;"&gt;ON &lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;SampleCustomers &lt;span style="color:blue;"&gt;REBUILD&lt;/span&gt;&lt;span style="color:gray;"&gt;;
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;After the rebuild, the index is back toward the end of the file, but it’s also back in order:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_05_13DB27CF.png"&gt;&lt;img title="VizDemo1_05" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;float:none;padding-top:0px;padding-left:0px;margin-left:auto;border-left:0px;display:block;padding-right:0px;margin-right:auto;" border="0" alt="VizDemo1_05" src="http://sqlblog.com/blogs/merrill_aldrich/VizDemo1_05_thumb_1C5E8719.png" width="1028" height="494" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, in light of this information, imagine nightly re-indexing on a database with … &lt;strong&gt;AutoShrink!&lt;/strong&gt; &amp;lt;shudder&amp;gt;&lt;/p&gt;</description></item><item><title>Visualizing Data File Layout I</title><link>http://sqlblog.com/blogs/merrill_aldrich/archive/2013/01/22/visualizing-data-file-layout-i.aspx</link><pubDate>Tue, 22 Jan 2013 22:50:34 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:47250</guid><dc:creator>merrillaldrich</dc:creator><description>&lt;p&gt;Part 1 of a blog series visually demonstrating the layout of objects on data pages in SQL Server&lt;/p&gt;  &lt;p&gt;Some years ago a gentleman called &lt;a href="http://sqlblogcasts.com/blogs/danny/default.aspx"&gt;Danny Gould&lt;/a&gt; created a free tool called &lt;a href="http://internalsviewer.codeplex.com/"&gt;Internals Viewer for SQL Server&lt;/a&gt;. I’m a visual sort of guy, and I always thought it would be fun and educational to make a simple visualizer, like the one he created, in order to view how objects are laid out in SQL Server files, and to use it to demonstrate how operations like re-index and shrink affect the layout of files.&lt;/p&gt;  &lt;p&gt;To that end, and a little bit reinventing the wheel truth be told, I spent this past holiday creating a simple .NET app that renders the file layout of a database into a color-coded bitmap:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/FileLayoutViewer01_48CAE32A.png"&gt;&lt;img title="FileLayoutViewer01" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="FileLayoutViewer01" src="http://sqlblog.com/blogs/merrill_aldrich/FileLayoutViewer01_thumb_586D7EEC.png" width="824" height="376" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Fig 1&lt;/p&gt;  &lt;p&gt;The app can scan the pages in a database, grab the header output from DBCC PAGE, parse that, and create a structure with a few key bits of information about every page. It then renders a bitmap from those structures showing a few things (Fig 1):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Each data object (index or table) partition is identified with a unique partition ID in SQL Server. Those IDs are used in this tool to color-code the output by object, from a color lookup table. Each color in the example screenshot represents the pages that are dedicated to a single partition of an object. This screenshot shows AdventureWorks, which doesn’t use the Enterprise Edition partitioning feature, so for this case each color represents one object – every object having exactly one partition in Standard Edition (or in databases that don’t use partitioning).&lt;/p&gt;    &lt;p&gt;Unallocated pages are shown as gray gaps. These are regions that are part of the physical file(s), but not used to store anything.&lt;/p&gt;    &lt;p&gt;The app flags pages at the end of any fragment of an object using a darker colored band, so it will reveal any non-contiguous structures in the data file(s). Sometimes these happen at the end of a region of the file where one object is stored, but, interestingly, sometimes these can happen in the middle – as shown in the image above where a dark band interrupts a continuous region of the same color.&lt;/p&gt;    &lt;p&gt;The app has some very basic mouse-over capability where you can run the mouse over the image and the text fields at right will reveal information about the pages, including the object schema.table.index and partition, and also whether the page represents a fragmentation boundary.&lt;/p&gt;    &lt;p&gt;Finally, the app shows what page types are located where in the file using the narrower white/gray/black bands. White represents data or index pages, while other shades of gray or black indicate other kinds of system pages, per Paul Randal’s excellent blog post &lt;a href="http://www.sqlskills.com/blogs/paul/inside-the-storage-engine-anatomy-of-a-page/"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;/blockquote&gt;  &lt;h2&gt;The Pixels Already Tell a Story&lt;/h2&gt;  &lt;p&gt;So, what can we learn about the sample database in this image? Here are a few things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The part of the file shown in the bitmap is fairly dense. There aren’t big regions of unallocated space in the file. A gap in the allocated pages looks like this (enlarged):      &lt;br /&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/FileLayoutViewer02_6C869B75.png"&gt;&lt;img title="FileLayoutViewer02" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="FileLayoutViewer02" src="http://sqlblog.com/blogs/merrill_aldrich/FileLayoutViewer02_thumb_1354B1B6.png" width="206" height="194" /&gt;&lt;/a&gt;       &lt;br /&gt;Empty Region       &lt;br /&gt;&amp;#160; &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Objects in the file are not contiguous, and may “hop around.” That is, if you follow the linked list of pages that compose an index, a bunch of them will be in a row, and then there will be a page that links to the next page composing the index but it’ll be in a different location in the file. I’ve called these “frag boundaries” – pages that do link to another page, but where that next logical page isn’t the next physical page in the file. In the graphic the frag boundary pages are colored with a darker dithered pattern. You can mouse over these and look in the text fields at the right in the app, and see the page they link to.      &lt;br /&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/FileLayoutViewer03_495BB6DC.png"&gt;&lt;img title="FileLayoutViewer03" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="FileLayoutViewer03" src="http://sqlblog.com/blogs/merrill_aldrich/FileLayoutViewer03_thumb_7029CD1C.png" width="238" height="188" /&gt;&lt;/a&gt;       &lt;br /&gt;Fragment Boundaries       &lt;br /&gt;&amp;#160; &lt;br /&gt;      &lt;br /&gt;Sometimes the end of a fragment will be adjacent to pages from another object, but it can be the case that there’s a fragment boundary in the middle of the pages for one object – it’s just that the linked list goes up to that point in the file, but then the next page in the index (in index order) isn’t the next page in the file, even though the next page in the file is part of the same object. Imagine a page split in the “middle” of an index – the existing page with half the rows stays in place, and a new page with the other half of the rows gets created in the middle of the logical index order but possibly stored in some other location in the physical file.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Right at the very beginning of the file there’s a special sequence of metadata pages that describe the database, allocations, and so on (again, well documented by Paul Randal). In our diagram this shows up as a series of pages at top left with varying page type (the gray and white) indicators:      &lt;br /&gt;&lt;a href="http://sqlblog.com/blogs/merrill_aldrich/FileLayoutViewer04_020660EA.png"&gt;&lt;img title="FileLayoutViewer04" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="FileLayoutViewer04" src="http://sqlblog.com/blogs/merrill_aldrich/FileLayoutViewer04_thumb_28D4772A.png" width="268" height="206" /&gt;&lt;/a&gt;       &lt;br /&gt;Database and file metadata pages &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In the next installment, I’ll run some test databases through this and we can see what more severe fragmentation looks like, the effect of GUID cluster keys, shrink, and how the data moves around in a re-index operation.&lt;/p&gt;  &lt;p&gt;Here’s a short demo video of the mouse-over working (quality is You-Tube limited):&lt;/p&gt;  &lt;div id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:a5c43597-8d84-4a1a-b897-db2f19356e72" class="wlWriterEditableSmartContent" style="float:none;padding-bottom:0px;padding-top:0px;padding-left:0px;margin:0px;display:inline;padding-right:0px;"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=q47a0L0_9Ws" target="_new"&gt;&lt;img src="http://sqlblog.com/blogs/merrill_aldrich/videof83e47a6713d_7D8FE022.jpg" style="border-style:none;" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="width:448px;clear:both;font-size:.8em;"&gt;Animated Screen Cap of Mouse-over&lt;/div&gt;&lt;/div&gt;</description></item><item><title>Windows Azure – Write, Run or Use Software</title><link>http://sqlblog.com/blogs/buck_woody/archive/2012/06/13/windows-azure-write-run-or-use-software.aspx</link><pubDate>Wed, 13 Jun 2012 22:47:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:43884</guid><dc:creator>BuckWoody</dc:creator><description>&lt;p&gt;&lt;a href="http://www.windowsazure.com/en-us/pricing/free-trial/" target="_blank"&gt;Windows Azure&lt;/a&gt; is a platform that has you covered, whether you need to write software, run software that is already written, or Install and use &amp;ldquo;canned&amp;rdquo; software whether you or someone else wrote it. Like any platform, it&amp;rsquo;s a set of tools you can use where it makes sense to solve a problem.&lt;/p&gt;
&lt;p&gt;You can click on the graphic below for a larger picture of these components, or download a poster with more details &lt;a title="Azure Poster Download" href="http://www.microsoft.com/en-us/download/details.aspx?id=35473&amp;amp;WT.mc_id=rss_alldownloads_all" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;a href="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79/1715.AzureArch.png"&gt;&lt;img src="http://sqlblog.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79/1715.AzureArch.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The primary location for Windows Azure information is located at &lt;a href="http://windowsazure.com" target="_blank"&gt;http://windowsazure.com&lt;/a&gt;. You can find everything there from the development kits for writing software to pricing, licensing and tutorials on all of that.&lt;/p&gt;
&lt;p&gt;I have a few links here for learning to use Windows Azure &amp;ndash; although it&amp;rsquo;s best if you focus not on the tools, &lt;em&gt;but what you want to solve&lt;/em&gt;. I&amp;rsquo;ve got it broken down here into various sections, so you can quickly locate things you want to know. I&amp;rsquo;ll include resources here from Microsoft and elsewhere &amp;ndash; I use these same resources in the Architectural Design Sessions (ADS) I do with my clients worldwide.&lt;/p&gt;
&lt;p&gt;There is also a great &lt;a href="http://sqlblog.com/b/alfredth/archive/2012/08/30/cloud-fundamentals-video-series.aspx" target="_blank"&gt;video series on Cloud Fundamentals here, if you have some time to watch them. It's a&amp;nbsp;great series that covers a lot of ground&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-weight:normal;"&gt;Write Software&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Also called &amp;ldquo;&lt;a href="http://www.microsoft.com/industry/government/guides/cloud_computing/5-PaaS.aspx" target="_blank"&gt;Platform as a Service&lt;/a&gt;&amp;rdquo; (PaaS), Windows Azure has lots of components you can use together or separately that allow you to write software in .NET or various Open Source languages to work completely online, or in partnership with code you have on-premises or both &amp;ndash; even if you&amp;rsquo;re using other cloud providers. Keep in mind that all of the features you see here can be used together, or independently. For instance, you might only use a Web Site, or use Storage, but you can use both together. You can access all of these components through standard REST API calls, or using our &lt;a href="http://www.windowsazure.com/en-us/develop/downloads/" target="_blank"&gt;Software Development Kit&amp;rsquo;s API&amp;rsquo;s, which are a lot easier&lt;/a&gt;. In any case, you simply use Visual Studio, Eclipse, Cloud9 IDE, or even a text editor to write your code from a Mac, PC or Linux.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/6545.Items_5F00_2.png"&gt;&lt;img style="margin:0px 8px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="Items" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/5305.Items_5F00_thumb.png" alt="Items" width="24" height="19" align="left" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;em&gt;Components you can use:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.windowsazure.com/en-us/home/scenarios/web-sites/" target="_blank"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/2251.link_5F00_5.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.windowsazure.com/en-us/home/scenarios/web-sites/" target="_blank"&gt;Azure Web Sites&lt;/a&gt;: Windows Azure Web Sites allow you to quickly write an deploy websites, without setting a Virtual Machine, installing a web server or configuring complex settings. They work alone, with other Windows Azure Web Sites, or with other parts of Windows Azure. Read more about &lt;a href="http://sqlblog.com/b/acoat/archive/2012/06/24/windows-azure-when-do-i-use-what.aspx" target="_blank"&gt;deciding to use Web Sites or Roles&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.windowsazure.com/en-us/home/features/cloud-services/" target="_blank"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/0601.link_5F00_6.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.windowsazure.com/en-us/home/features/cloud-services/" target="_blank"&gt;Web and Worker Roles&lt;/a&gt;: Windows Azure Web Roles give you a full stateless computing instance with Internet Information Services (IIS) installed and configured. Windows Azure Worker Roles give you a full stateless computing instance without Information Services (IIS) installed, often used in a "Services" mode. Scale-out is achieved either manually or programmatically under your control.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/ee924681.aspx" target="_blank"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/2337.link_5F00_7.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/ee924681.aspx" target="_blank"&gt;Storage&lt;/a&gt;: Windows Azure Storage types include &lt;a href="http://www.windowsazure.com/en-us/develop/net/how-to-guides/blob-storage/" target="_blank"&gt;Blobs&lt;/a&gt; to store raw binary data, &lt;a href="http://www.windowsazure.com/en-us/develop/net/how-to-guides/table-services/" target="_blank"&gt;Tables&lt;/a&gt; to use key/value pair data (like NoSQL data structures), &lt;a href="http://www.windowsazure.com/en-us/develop/net/how-to-guides/queue-service/" target="_blank"&gt;Queues&lt;/a&gt; that allow interaction between stateless roles, and a relational &lt;a href="http://www.windowsazure.com/en-us/develop/net/how-to-guides/sql-database/" target="_blank"&gt;SQL Server database&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.windowsazure.com/en-us/develop/net/fundamentals/hybrid-solutions/" target="_blank"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/2843.link_5F00_8.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.windowsazure.com/en-us/develop/net/fundamentals/hybrid-solutions/" target="_blank"&gt;Other Services&lt;/a&gt;: Windows Azure has many other services such as a &lt;a href="http://www.windowsazure.com/en-us/develop/net/how-to-guides/access-control/" target="_blank"&gt;security mechanism&lt;/a&gt;, a &lt;a href="http://www.windowsazure.com/en-us/develop/net/how-to-guides/cache/" target="_blank"&gt;Cache&lt;/a&gt; (memcacheD compliant), a &lt;a href="http://www.windowsazure.com/en-us/develop/net/how-to-guides/service-bus-topics/" target="_blank"&gt;Service Bus&lt;/a&gt;, a Traffic Manager and more. Once again, these features can be used with a Windows Azure project, or alone based on your needs.&lt;/p&gt;
&lt;p&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentColor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/2843.link_5F00_8.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;a href="http://www.windowsazure.com/en-us/home/scenarios/mobile-services/" target="_blank"&gt;Windows Azure Mobile Services&lt;/a&gt;: A simple framework service which enables you to quickly develop the back-end for mobile services. For the front-end, check out the &lt;a href="https://github.com/WindowsAzure-Toolkits/wa-toolkit-ios" target="_blank"&gt;iOS SDK&lt;/a&gt;, &lt;a href="http://blogs.technet.com/b/microsoft_blog/archive/2011/05/09/microsoft-announces-windows-azure-toolkits-for-ios-android-and-windows-phone.aspx" target="_blank"&gt;news about the Android SDK&lt;/a&gt;, and the &lt;a href="http://watwp.codeplex.com/" target="_blank"&gt;Windows Phone SDK&lt;/a&gt;.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.windowsazure.com/en-us/develop/overview/" target="_blank"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/1680.link_5F00_9.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.windowsazure.com/en-us/develop/overview/" target="_blank"&gt;Various Languages&lt;/a&gt;: Windows Azure supports the .NET stack of languages, as well as many Open-Source languages like Java, Python, PHP, Ruby, NodeJS, C++ and more.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-weight:normal;"&gt;Use Software&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Also called &amp;ldquo;&lt;a href="http://msdn.microsoft.com/en-us/library/bb507203.aspx" target="_blank"&gt;Software as a Service&lt;/a&gt;&amp;rdquo; (SaaS) this often means consumer or business-level software like Hotmail or Office 365. In other words, you simply log on, use the software, and log off &amp;ndash; there&amp;rsquo;s nothing to install, and little to even configure. For the Information Technology professional, however, It&amp;rsquo;s not quite the same. We want software that provides services, but in a platform. That means we want things like Hadoop or other software we don&amp;rsquo;t want to have to install and configure.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/6545.Items_5F00_2.png"&gt;&lt;img style="margin:0px 8px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="Items" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/5305.Items_5F00_thumb.png" alt="Items" width="24" height="19" align="left" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;em&gt;Components you can use:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.youtube.com/watch?v=MpsIh2HwdPo"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/2744.link_5F00_10.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.youtube.com/watch?v=MpsIh2HwdPo" target="_blank"&gt;Kits&lt;/a&gt;: Various software &amp;ldquo;kits&amp;rdquo; or packages are supported with just a few clicks, such as Umbraco, Wordpress, and others.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.windowsazure.com/en-us/home/features/media-services/" target="_blank"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/6557.link_5F00_11.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.windowsazure.com/en-us/home/features/media-services/" target="_blank"&gt;Windows Azure Media Services&lt;/a&gt;: Windows Azure Media Services is a suite of services that allows you to upload media for encoding, processing and even streaming &amp;ndash; or even one or more of those functions. We can add DRM and even commercials to your media if you like. Windows Azure Media Services is used to stream large events all the way down to small training videos.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.windowsazure.com/en-us/home/scenarios/big-data/" target="_blank"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/3821.link_5F00_12.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.windowsazure.com/en-us/home/scenarios/big-data/" target="_blank"&gt;High Performance Computing and &amp;ldquo;Big Data&amp;rdquo;&lt;/a&gt;: Windows Azure allows you to scale to huge workloads using a few clicks to deploy &lt;a href="https://www.hadooponazure.com/" target="_blank"&gt;Hadoop&lt;/a&gt; Clusters or the &lt;a href="http://msdn.microsoft.com/en-us/library/hh560251(v=vs.85).aspx" target="_blank"&gt;High Performance Computing (HPC) nodes&lt;/a&gt;, accepting HPC Jobs, Pig and Hive Jobs, and even interfacing with Microsoft Excel.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://datamarket.azure.com/" target="_blank"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/7853.link_5F00_13.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="https://datamarket.azure.com/" target="_blank"&gt;Windows Azure Marketplace&lt;/a&gt;: Windows Azure Marketplace offers data and programs you can quickly implement and use &amp;ndash; some free, some for-fee.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-weight:normal;"&gt;Run Software&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Also known as &amp;ldquo;&lt;a href="http://sqlblog.com/b/jmeier/archive/2010/02/11/software-as-a-service-saas-platform-as-a-service-paas-and-infrastructure-as-a-service-iaas.aspx" target="_blank"&gt;Infrastructure as a Service&lt;/a&gt;&amp;rdquo; (IaaS), this offering allows you to build or simply choose a Virtual Machine to run server-based software.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/6545.Items_5F00_2.png"&gt;&lt;img style="margin:0px 8px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="Items" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/5305.Items_5F00_thumb.png" alt="Items" width="24" height="19" align="left" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;em&gt;Components you can use:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.windowsazure.com/en-us/home/scenarios/virtual-machines/" target="_blank"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/1680.link_5F00_14.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.windowsazure.com/en-us/home/scenarios/virtual-machines/" target="_blank"&gt;Persistent Virtual Machines&lt;/a&gt;: You can choose to install Windows Server, Windows Server with Active Directory, with SQL Server, or even SharePoint from a pre-configured gallery. You can configure your own server images with standard Hyper-V technology and load them yourselves &amp;ndash; and even bring them back when you&amp;rsquo;re done. As a new offering, we also even allow you to select various distributions of Linux &amp;ndash; a first for Microsoft.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/gg432997.aspx" target="_blank"&gt;&lt;img style="margin:0px 5px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/7041.link_5F00_15.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/gg432997.aspx" target="_blank"&gt;Windows Azure Connect&lt;/a&gt;: You can connect your on-premises networks to Windows Azure Instances.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/ee924681.aspx" target="_blank"&gt;&lt;img style="margin:0px 3px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/2744.link_5F00_16.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/ee924681.aspx" target="_blank"&gt;Storage&lt;/a&gt;: Windows Azure Storage can be used as a remote backup, a hybrid storage location and more using software or even hardware appliances.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-weight:normal;"&gt;Decision Matrix&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/2742.tool_5F00_2.png"&gt;&lt;img style="border:0px currentcolor;display:inline;background-image:none;" title="tool" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/3821.tool_5F00_thumb.png" alt="tool" width="29" height="30" border="0" /&gt;&lt;/a&gt;With all of these options, you can use Windows Azure to solve just about any computing problem. It&amp;rsquo;s often hard to know when to use something on-premises, in the cloud, and what kind of service to use.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve used a decision matrix in the last couple of years to take a particular problem and choose the proper technology to solve it. It&amp;rsquo;s all about options &amp;ndash; there is no &amp;ldquo;silver bullet&amp;rdquo;, whether that&amp;rsquo;s Windows Azure or any other set of functions. I take the problem, decide which particular component I want to own and control &amp;ndash; and choose the column that has that box darkened. For instance, if I have to control the wiring for a solution (a requirement in some military and government installations), that means the &amp;ldquo;Networking&amp;rdquo; component needs to be dark, and so I select the &amp;ldquo;On Premises&amp;rdquo; column for that particular solution. If I just need the solution provided and I want no control at all, I can look as &amp;ldquo;Software as a Service&amp;rdquo; solutions.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/2251.image6.png"&gt;&lt;img style="border:0px currentcolor;margin-right:auto;margin-left:auto;float:none;display:block;background-image:none;" title="image" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/1273.image6_5F00_thumb.png" alt="image" width="663" height="487" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-weight:normal;"&gt;Security, Pricing, and Other Info&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://www.windowsazure.com/en-us/support/trust-center/" target="_blank"&gt;&lt;img style="margin:0px 3px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/0601.link_5F00_d062d746_2D00_5265_2D00_40d7_2D00_aaaa_2D00_02275b1cedf9.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.windowsazure.com/en-us/support/trust-center/" target="_blank"&gt;Security&lt;/a&gt;: Security is one of the first questions you should ask in any distributed computing environment. We have certification info, coding guidelines and more, even a general &amp;ldquo;Request for Information&amp;rdquo; &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=26647" target="_blank"&gt;RFI Response already created for you&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://www.windowsazure.com/en-us/pricing/purchase-options/" target="_blank"&gt;&lt;img style="margin:0px 3px 0px 0px;border:0px currentcolor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/0284.link_5F00_c1797794_2D00_6178_2D00_4357_2D00_9af5_2D00_4729f7f7aa4f.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.windowsazure.com/en-us/pricing/purchase-options/" target="_blank"&gt;Pricing&lt;/a&gt;: Are there licenses? &lt;a href="http://www.windowsazure.com/en-us/pricing/calculator/?scenario=web" target="_blank"&gt;How much does this cost&lt;/a&gt;? &lt;a href="http://sqlblog.com/b/buckwoody/archive/2011/11/08/developing-a-cost-model-for-cloud-applications.aspx" target="_blank"&gt;Is there a way to estimate the costs in this new environment&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/b/davidmcg/archive/2012/06/14/azure-action-community-newsletter-13th-june-2012.aspx" target="_blank"&gt;&lt;img style="margin:0px 3px 0px 0px;border:0px currentColor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/0284.link_5F00_c1797794_2D00_6178_2D00_4357_2D00_9af5_2D00_4729f7f7aa4f.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/a&gt;New Features: Many new features were added to Windows Azure - and you can keep up to date with community information released monthly here: &lt;a href="http://sqlblog.com/b/davidmcg/"&gt;http://blogs.msdn.com/b/davidmcg/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style="margin:0px 3px 0px 0px;border:0px currentColor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/0284.link_5F00_c1797794_2D00_6178_2D00_4357_2D00_9af5_2D00_4729f7f7aa4f.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/p&gt;
&lt;p&gt;Windows Azure Cookbooks: Great resource for architecture solutions - &lt;a href="http://www.notsotrivial.net/blog/category/Architecture.aspx"&gt;http://www.notsotrivial.net/blog/category/Architecture.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style="margin:0px 3px 0px 0px;border:0px currentColor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/0284.link_5F00_c1797794_2D00_6178_2D00_4357_2D00_9af5_2D00_4729f7f7aa4f.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/p&gt;
&lt;p&gt;Support: &lt;a href="http://support.microsoft.com/kb/2721672" target="_blank"&gt;Software Support on Virtual Machines&lt;/a&gt;,&amp;nbsp;&lt;a href="https://www.windowsazure.com/en-us/support/contact/" target="_blank"&gt;general support&lt;/a&gt;, &lt;a href="http://www.windowsazure.com/en-us/support/plans/" target="_blank"&gt;support plans&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style="margin:0px 3px 0px 0px;border:0px currentColor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/0284.link_5F00_c1797794_2D00_6178_2D00_4357_2D00_9af5_2D00_4729f7f7aa4f.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;/p&gt;
&lt;p&gt;Hands-On Labs: &lt;a href="http://msdn.microsoft.com/en-us/jj618399"&gt;http://msdn.microsoft.com/en-us/jj618399&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style="margin:0px 3px 0px 0px;border:0px currentColor;float:left;display:inline;background-image:none;" title="link" src="http://sqlblog.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-79-79-metablogapi/0284.link_5F00_c1797794_2D00_6178_2D00_4357_2D00_9af5_2D00_4729f7f7aa4f.png" alt="link" width="24" height="24" align="left" border="0" /&gt;&lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=35524&amp;amp;WT.mc_id=rss_alldownloads_all" target="_blank"&gt;Windows Azure Capability Discussion Presentation&lt;/a&gt; and &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=35527&amp;amp;WT.mc_id=rss_alldownloads_all" target="_blank"&gt;Windows Azure Solution Implementer Guide&lt;/a&gt; and &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=35534&amp;amp;WT.mc_id=rss_alldownloads_all" target="_blank"&gt;Windows Azure Business Priorities Guide&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item><item><title>Big Data - A Microsoft Tools Approach</title><link>http://sqlblog.com/blogs/buck_woody/archive/2012/02/20/big-data-a-microsoft-tools-approach.aspx</link><pubDate>Mon, 20 Feb 2012 21:16:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:41832</guid><dc:creator>BuckWoody</dc:creator><description>&lt;p&gt;&lt;em&gt;&lt;span style="color:#c0504d;"&gt;(As with all of these types of posts, check the date of the latest update I&amp;rsquo;ve made here. Anything older than 6 months is probably out of date, given the speed with which we release new features into Windows and SQL Azure)&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t normally like to discuss things in terms of tools. I find that whenever you start with a given tool (or even a tool stack) it&amp;rsquo;s too easy to fit the problem to the tool(s), rather than the other way around as it should be.&lt;/p&gt;
&lt;p&gt;That being said, it&amp;rsquo;s often useful to have an example to work through to better understand a concept. But like many ideas in Computer Science, &amp;ldquo;Big Data&amp;rdquo; is too broad a term in use to show a single example that brings out the multiple processes, use-cases and patterns you can use it for.&lt;/p&gt;
&lt;p&gt;So we turn to a description of the tools you can use to analyze large data sets. &amp;ldquo;Big Data&amp;rdquo; is a term used lately to describe data sets that have the &amp;ldquo;&lt;a href="http://radar.oreilly.com/2012/01/what-is-big-data.html" target="_blank"&gt;Four V&amp;rsquo;s&lt;/a&gt;&amp;rdquo;&amp;nbsp; as a characteristic, but I have a simpler definition I like to use:&lt;/p&gt;
&lt;p align="center"&gt;&lt;em&gt;&lt;span style="color:#0000ff;font-size:small;"&gt;Big Data involves a data set too large to process in a reasonable period of time&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I realize that&amp;rsquo;s a bit broad, but in my mind it answers the question and is fairly future-proof. The general idea is that you want to analyze some data, and using whatever current methods, storage, compute and so on that you have at hand it doesn&amp;rsquo;t allow you to finish processing it in a time period that you are comfortable with. I&amp;rsquo;ll explain some new tools you can use for this processing.&lt;/p&gt;
&lt;p&gt;Yes, this post is Microsoft-centric. There are probably posts from other vendors and open-source that cover this process in the way they best see fit. And of course you can always &amp;ldquo;mix and match&amp;rdquo;, meaning using Microsoft for one or more parts of the process and other vendors or open-source for another. I never advise that you use any one vendor blindly - educate yourself, examine the facts, perform some tests and choose whatever mix of technologies best solves your problem.&lt;/p&gt;
&lt;p&gt;At the risk of being vendor-specific, and probably incomplete, I use the following short list of tools Microsoft has for working with &amp;ldquo;Big Data&amp;rdquo;. There is no single package that performs all phases of analysis. These tools are what I use; they should not be taken as a Microsoft authoritative testament to the toolset we&amp;rsquo;ll finalize for a given problem-space. In fact, that&amp;rsquo;s the key: find the problem and then fit the tools to that.&lt;/p&gt;
&lt;h2&gt;Process Types&lt;/h2&gt;
&lt;p&gt;I break up the analysis of the data into two process types. The first is examining and processing the data &lt;em&gt;in-line&lt;/em&gt;, meaning as the data passes through some process. The second is a &lt;em&gt;store-analyze-present&lt;/em&gt; process.&lt;/p&gt;
&lt;h2&gt;Processing Data In-Line&lt;/h2&gt;
&lt;p&gt;Processing data in-line means that the data doesn&amp;rsquo;t have a destination - it remains in the source system. But as it moves from an input or is routed to storage within the source system, various methods are available to examine the data as it passes, and either trigger some action or create some analysis.&lt;/p&gt;
&lt;p&gt;You might not think of this as &amp;ldquo;Big Data&amp;rdquo;, but in fact it can be. Organizations have huge amounts of data stored in multiple systems. Many times the data from these systems do not end up in a database for evaluation. There are options, however, to evaluate that data real-time and either act on the data or perhaps copy or stream it to another process for evaluation.&lt;/p&gt;
&lt;p&gt;The advantage of an in-stream data analysis is that you don&amp;rsquo;t necessarily have to store the data again to work with it. That&amp;rsquo;s also a disadvantage - depending on how you architect the solution, you might not retain a historical record. One method of dealing with this requirement is to trigger a rollup collection or a more detailed collection based on the event.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;StreamInsight &lt;/strong&gt;- StreamInsight is Microsoft&amp;rsquo;s &amp;ldquo;Complex Event Processing&amp;rdquo; or CEP engine. This product, hooked into SQL Server 2008R2, has multiple ways of interacting with a data flow. You can create adapters to talk with systems, and then examine the data mid-stream and create triggers to do something with it. You can read more about StreamInsight here: &lt;a title="http://msdn.microsoft.com/en-us/library/ee391416(v=sql.110).aspx" href="http://msdn.microsoft.com/en-us/library/ee391416(v=sql.110).aspx"&gt;http://msdn.microsoft.com/en-us/library/ee391416(v=sql.110).aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BizTalk &lt;/strong&gt;- When there is more latency available between the initiation of the data and its processing, you can use Microsoft BizTalk. This is a message-passing and Service Bus oriented tool, and it can also be used to join system&amp;rsquo;s data together than normally does not have a direct link, for instance a Mainframe system to SQL Server. You can learn more about BizTalk here: &lt;a href="http://www.microsoft.com/biztalk/en/us/overview.aspx"&gt;http://www.microsoft.com/biztalk/en/us/overview.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET and the Windows Azure Service Bus &lt;/strong&gt;- Along the same lines as BizTalk but with a more programming-oriented design are the Windows and Windows Azure Service Bus tools. The Service Bus allows you to pass messages as well, and opens up web interactions and even inter-company routing. BizTalk can do this as well, but the Service Bus tools use an API approach for designing the flow and interfaces you want. The Service Bus offerings are also intended as near real-time, not as a streaming interface. You can learn more about the Windows Azure Service Bus here: &lt;a href="http://www.windowsazure.com/en-us/home/tour/service-bus/"&gt;http://www.windowsazure.com/en-us/home/tour/service-bus/&lt;/a&gt; and more about the Event Processing side here: &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd569756.aspx"&gt;http://msdn.microsoft.com/en-us/magazine/dd569756.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Store-Analyze-Present&lt;/h2&gt;
&lt;p&gt;A more traditional approach with an organization&amp;rsquo;s data is to store the data and analyze it out-of-band. This began with simply running code over a data store, but as locking and blocking became an issue on a file system, Relational Database Management Systems (RDBMs) were created. Over time a distinction was made between data used in an online processing system, meant to be highly available for writing data (OLTP) and systems designed for analytical and reporting purposes (OLAP).&lt;/p&gt;
&lt;p&gt;Later the data grew larger than these systems were designed for, primarily due to consistency requirements. In analysis, however, consistency isn&amp;rsquo;t always a requirement, and so file-based systems for that analysis were re-introduced from the Mainframe concepts, with new technology layered in for speed and size.&lt;/p&gt;
&lt;p&gt;I normally break up the process of analyzing large data sets into four phases:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Source and Transfer &lt;/em&gt;- Obtaining the data at its source and transferring or loading it into the storage; optionally transforming it along the way&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Store and Process&lt;/em&gt; - Data is stored on some sort of persistence, and in some cases an engine handles the acquisition and placement on persistent storage, as well as retrieval through an interface.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;em&gt;Analysis &lt;/em&gt;- A new layer introduced with &amp;ldquo;Big Data&amp;rdquo; is a separate analysis step. This is dependent on the engine or storage methodology, is often programming language or script based, and sometimes re-introduces the analysis back into the data. Some engines and processes combine this function into the previous phase.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Presentation&lt;/em&gt; - In most cases, the data wants a graphical representation to comprehend, especially in a series or trend analysis. In other cases a simple symbolic representation, similar to the &amp;ldquo;dashboard&amp;rdquo; elements in a Business Intelligence suite. Presentation tools may also have an analysis or refinement capability to allow end-users to work with the data sets. As in the Analysis phase, some methodologies bundle in the Analysis and Presentation phases into one toolset.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Source and Transfer&lt;/h3&gt;
&lt;p&gt;You&amp;rsquo;ll notice in this area, along with those that follow, Microsoft is adopting not only its own technologies but those within open-source. This is a positive sign, and means that you will have a best-of-breed, supported set of tools to move the data from one location to another. Traditional file-copy, File Transfer Protocol and more are certainly options, but do not normally deal with moving datasets.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve already mentioned the ability of a streaming tool to push data into a store-analyze-present model, so I&amp;rsquo;ll follow up that discussion with the tools that can extract data from one source and place it in another.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;SQL Server Integration Services (SSIS)/SQL Server Bulk Copy Program (BCP)&lt;/span&gt; &lt;/strong&gt;- SSIS is a SQL Server tool used to move data from one location to another, and optionally perform transform or other processes as it does so. You are not limited to working with SQL Server data - in fact, almost any modern source of data from text to various database platforms is available to move to various systems. It is also extremely fast and has a rich development environment. You can learn more about SSIS here: &lt;a href="http://msdn.microsoft.com/en-us/library/ms141026.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms141026.aspx&lt;/a&gt; BCP is a tool that has been used with SQL Server data since the first releases; it has multiple sources and destinations as well. It is a command-line utility,and has some limited transform capabilities. You can learn more about BCP here: &lt;a href="http://msdn.microsoft.com/en-us/library/ms162802.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms162802.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="color:#800000;"&gt;Sqoop&lt;/span&gt; &lt;/span&gt;&lt;/strong&gt;- Tied to Microsoft&amp;rsquo;s latest announcements with Hadoop on Windows and Windows Azure, Sqoop is a tool that is used to move data between SQL Server 2008R2 (and higher)&amp;nbsp;and Hadoop, quickly and efficiently. You can read more about that in the Readme file here: &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=27584"&gt;http://www.microsoft.com/download/en/details.aspx?id=27584&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#800000;"&gt;&lt;strong&gt;Application Programming Interfaces&lt;/strong&gt;&lt;/span&gt; - API&amp;rsquo;s exist in most every major language that can connect to one data source, access data, optionally transforming it and storing it in another system. Most every dialect of&amp;nbsp; the .NET-based languages contain methods to perform this task.&lt;/p&gt;
&lt;h3&gt;Store and Process&lt;/h3&gt;
&lt;p&gt;Data at rest is normally used for historical analysis. In some cases this analysis is performed near real-time, and in others historical data is analyzed periodically. Systems that handle data at rest range from simple storage to active management engines.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;SQL Server&lt;/span&gt;&lt;/strong&gt; - Microsoft&amp;rsquo;s flagship RDBMS can indeed store massive amounts of complex data. I am familiar with a two systems in excess of 300 Terabytes of federated data, and the &lt;a href="http://pan-starrs.ifa.hawaii.edu/public/" target="_blank"&gt;Pan-Starrs&lt;/a&gt; project is designed to handle 1+ Petabyte of data. The theoretical limit of SQL Server DataCenter edition is 540 Petabytes. SQL Server is an engine, so the data access and storage is handled in an abstract layer that also handles concurrency for ACID properties. You can learn more about SQL Server here: &lt;a href="http://www.microsoft.com/sqlserver/en/us/product-info/compare.aspx"&gt;http://www.microsoft.com/sqlserver/en/us/product-info/compare.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;SQL Azure Federations&lt;/span&gt;&lt;/strong&gt; - SQL Azure is a database service from Microsoft associated with the Windows Azure platform. Database Servers are multi-tenant, but are shared across a &amp;ldquo;fabric&amp;rdquo; that moves active databases for redundancy and performance. Copies of all databases are kept triple-redundant with a consistent commitment model. Databases are (at this writing - check &lt;a href="http://WindowsAzure.com"&gt;http://WindowsAzure.com&lt;/a&gt; for the latest) capped at a 150 GB size limit per database. However, Microsoft released a &amp;ldquo;Federation&amp;rdquo; technology, allowing you to query a head node and have the data federated out to multiple databases. This improves both size and performance. You can read more about SQL Azure Federations here: &lt;a href="http://social.technet.microsoft.com/wiki/contents/articles/2281.federations-building-scalable-elastic-and-multi-tenant-database-solutions-with-sql-azure.aspx"&gt;http://social.technet.microsoft.com/wiki/contents/articles/2281.federations-building-scalable-elastic-and-multi-tenant-database-solutions-with-sql-azure.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;Analysis Services&lt;/span&gt;&lt;/strong&gt; - The Business Intelligence engine within SQL Server, called Analysis Services, can also handle extremely large data systems. In addition to traditional BI data store layouts (ROLAP, MOLAP and HOLAP), the latest version of SQL Server introduces the Vertipaq column-storage technology allowing more direct access to data and a different level of compression. You can read more about Analysis Services here: &lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/business-intelligence/analysis-services.aspx"&gt;http://www.microsoft.com/sqlserver/en/us/solutions-technologies/business-intelligence/analysis-services.aspx&lt;/a&gt; and more about Vertipaq here: &lt;a href="http://msdn.microsoft.com/en-us/library/hh212945(v=SQL.110).aspx"&gt;http://msdn.microsoft.com/en-us/library/hh212945(v=SQL.110).aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#800000;"&gt;&lt;strong&gt;Parallel Data Warehouse &lt;/strong&gt;&lt;/span&gt;- The Parallel Data Warehouse (PDW) offering from Microsoft is largely described by the title. Accessed in multiple ways including using Transact-SQL (the Microsoft dialect of the Structured Query Language), &lt;a href="http://sqlpdw.com/2010/07/what-mpp-means-to-sql-server-parallel-data-warehouse/" target="_blank"&gt;This is an MPP appliance&lt;/a&gt;&amp;nbsp;scaling in parallel to extremely large datasets. It is a hardware and software offering - you can learn more about it here: &lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/data-warehousing/pdw.aspx"&gt;http://www.microsoft.com/sqlserver/en/us/solutions-technologies/data-warehousing/pdw.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;HPC Server&lt;/span&gt;&lt;/strong&gt; - Microsoft&amp;rsquo;s High-Performance Computing version of Windows Server deals not only with large data sets, but with extremely complicated computing requirements. A scale-out architecture and inter-operation with Linux systems, as well as dozens of applications pre-written to work with this server make this a capable &amp;ldquo;Big Data&amp;rdquo; system. It is a mature offering, with a long track record of success in scientific, financial and other areas of data processing. It is available both on premises and in Windows Azure, and also in a hybrid of both models, allowing you to &amp;ldquo;rent&amp;rdquo; a super-computer when needed. You can read more about it here: &lt;a href="http://www.microsoft.com/hpc/en/us/product/cluster-computing.aspx"&gt;http://www.microsoft.com/hpc/en/us/product/cluster-computing.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;Hadoop&lt;/span&gt;&lt;/strong&gt; - Pairing up with Hortonworks, Microsoft has released the Hadoop Open-Source system -&amp;nbsp; including HDFS and a Map/Reduce standardized software, Hive and Pig - on Windows and the Windows Azure platform. This is not a customized version; off-the-shelf concepts and queries work well here. You can read more about Hadoop here: &lt;a href="http://hadoop.apache.org/common/docs/current/"&gt;http://hadoop.apache.org/common/docs/current/&lt;/a&gt; and you can read more about Microsoft&amp;rsquo;s offerings here: &lt;a href="http://hortonworks.com/partners/microsoft/"&gt;http://hortonworks.com/partners/microsoft/&lt;/a&gt;&amp;nbsp;and here: &lt;a href="http://social.technet.microsoft.com/wiki/contents/articles/6204.hadoop-based-services-for-windows.aspx"&gt;http://social.technet.microsoft.com/wiki/contents/articles/6204.hadoop-based-services-for-windows.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;Windows and Azure Storage&lt;/span&gt;&lt;/strong&gt; - Although not an engine - other than a triple-redundant, immediately consistent commit - Windows Azure can hold terabytes of information and make it available to everything from the R programming language to the Hadoop offering. Binary storage (Blobs) and Table storage (Key-Value Pair) data can be queried across a distributed environment. You can learn more about Windows Azure storage here: &lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/gg433040.aspx"&gt;http://msdn.microsoft.com/en-us/library/windowsazure/gg433040.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Analysis&lt;/h3&gt;
&lt;p&gt;In a &amp;ldquo;Big Data&amp;rdquo; environment, it&amp;rsquo;s not unusual to have a specialized set of tasks for analyzing and even interpreting the data. This is a new field called &amp;ldquo;data Science&amp;rdquo;, with a requirement not only for computing, but also a heavy emphasis on math.&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#800000;"&gt;&lt;strong&gt;Transact-SQL &lt;/strong&gt;&lt;/span&gt;- T-SQL is the dialect of the Structured Query Language used by Microsoft. It includes not only robust selection, updating and manipulating of data, but also analytical and domain-level interrogation as well. It can be used on SQL Server, PDW and ODBC data sources. You can read more about T-SQL here: &lt;a href="http://msdn.microsoft.com/en-us/library/bb510741.aspx"&gt;http://msdn.microsoft.com/en-us/library/bb510741.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;Multidimensional Expressions and Data Analysis Expressions&lt;/span&gt;&lt;/strong&gt; - The MDX and DAX languages allow you to query multidimensional data models that do not fit well with typical two-plane query languages. Pivots, aggregations and more are available within these constructs to query and work with data in Analysis Services. You can read more about MDX here: &lt;a href="http://msdn.microsoft.com/en-us/library/ms145506(v=sql.110).aspx"&gt;http://msdn.microsoft.com/en-us/library/ms145506(v=sql.110).aspx&lt;/a&gt; and more about DAX here: &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=28572"&gt;http://www.microsoft.com/download/en/details.aspx?id=28572&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;HPC Jobs and Tasks &lt;/span&gt;&lt;/strong&gt;- Work submitted to the Windows HPC Server has a particular job - essentially a reservation request for resources. Within a job you can submit tasks, such as parametric sweeps and more. You can learn more about Jobs and Tasks here: &lt;a href="http://technet.microsoft.com/en-us/library/cc719020(v=ws.10).aspx"&gt;http://technet.microsoft.com/en-us/library/cc719020(v=ws.10).aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;HiveQL &lt;/span&gt;&lt;/strong&gt;- HiveQL is the language used to query a Hive object running on Hadoop. You can see a tutorial on that process here: &lt;a href="http://social.technet.microsoft.com/wiki/contents/articles/6628.aspx"&gt;http://social.technet.microsoft.com/wiki/contents/articles/6628.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;Piglatin &lt;/span&gt;&lt;/strong&gt;- Piglatin is the submission language for the Pig implementation on Hadoop. An example of that process is here: &lt;a href="http://sqlblog.com/b/avkashchauhan/archive/2012/01/10/running-apache-pig-pig-latin-at-apache-hadoop-on-windows-azure.aspx"&gt;http://blogs.msdn.com/b/avkashchauhan/archive/2012/01/10/running-apache-pig-pig-latin-at-apache-hadoop-on-windows-azure.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;Application Programming Interfaces &lt;/span&gt;&lt;/strong&gt;- Almost all of the analysis offerings have associated API&amp;rsquo;s - of special note is Microsoft Research&amp;rsquo;s Infer.NET, a new language construct for framework for running Bayesian inference in graphical models, as well as probabilistic programming. You can read more about Infer.NET here: &lt;a href="http://research.microsoft.com/en-us/um/cambridge/projects/infernet/"&gt;http://research.microsoft.com/en-us/um/cambridge/projects/infernet/&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Presentation&lt;/h3&gt;
&lt;p&gt;Lots of tools work in presenting the data once you have done the primary analysis. In fact, there&amp;rsquo;s a great video of a comparison of various tools here: &lt;a href="http://msbiacademy.com/Lesson.aspx?id=73"&gt;http://msbiacademy.com/Lesson.aspx?id=73&lt;/a&gt; Primarily focused on Business Intelligence. That term itself is now not as completely defined, but the tools I&amp;rsquo;ll show below can be used in multiple ways - not just traditional Business Intelligence scenarios. Application Programming Interfaces (API&amp;rsquo;s) can also be used for presentation; but I&amp;rsquo;ll focus here on &amp;ldquo;out of the box&amp;rdquo; tools.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;Excel&lt;/span&gt;&lt;/strong&gt; - Microsoft&amp;rsquo;s Excel can be used not only for single-desk analysis of data sets, but with larger datasets as well. It has interfaces into SQL Server, Analysis Services, can be connected to the PDW, and is a first-class job submission system for the Windows HPC Server. You can watch a video about Excel and big data here: &lt;a href="http://www.microsoft.com/en-us/showcase/details.aspx?uuid=e20b7482-11c9-4965-b8f0-7fb6ac7a769f"&gt;http://www.microsoft.com/en-us/showcase/details.aspx?uuid=e20b7482-11c9-4965-b8f0-7fb6ac7a769f&lt;/a&gt;&amp;nbsp;and you can also connect Excel to Hadoop: &lt;a href="http://social.technet.microsoft.com/wiki/contents/articles/how-to-connect-excel-to-hadoop-on-azure-via-hiveodbc.aspx"&gt;http://social.technet.microsoft.com/wiki/contents/articles/how-to-connect-excel-to-hadoop-on-azure-via-hiveodbc.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;Reporting Services&lt;/span&gt;&lt;/strong&gt; - Reporting Services is a SQL Server tool that can query and show data from multiple sources, all at once. It can also be used with Analysis Services. You can read more about Reporting Services here: &lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/business-intelligence/reporting-services.aspx"&gt;http://www.microsoft.com/sqlserver/en/us/solutions-technologies/business-intelligence/reporting-services.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;Power View&lt;/span&gt;&lt;/strong&gt; - Power View is a &amp;ldquo;Self-Service&amp;rdquo; Business Intelligence reporting tool, which can work with on-premises data in addition to SQL Azure and other data. You can read more about it and see videos of Power View in action here: &lt;a href="http://www.microsoft.com/sqlserver/en/us/future-editions/business-intelligence/SQL-Server-2012-reporting-services.aspx"&gt;http://www.microsoft.com/sqlserver/en/us/future-editions/business-intelligence/SQL-Server-2012-reporting-services.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#800000;"&gt;SharePoint Services -&lt;/span&gt;&lt;/strong&gt; Microsoft has rolled several capable tools in SharePoint as &amp;ldquo;Services&amp;rdquo;. This has the advantage of being able to integrate into the working environment of many companies. You can read more about&amp;nbsp; lots of these reporting and analytic presentation tools here: &lt;a href="http://technet.microsoft.com/en-us/sharepoint/ee692578"&gt;http://technet.microsoft.com/en-us/sharepoint/ee692578&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This is by no means an exhaustive list - more capabilities are added all the time to Microsoft&amp;rsquo;s products, and things will surely shift and merge as time goes on. Expect today&amp;rsquo;s &amp;ldquo;Big Data&amp;rdquo; to be tomorrow&amp;rsquo;s &amp;ldquo;Laptop Environment&amp;rdquo;.&lt;/p&gt;</description></item><item><title>Windows Azure Storage (WAS) Internals - Achieving Consistency</title><link>http://sqlblog.com/blogs/buck_woody/archive/2011/12/13/windows-azure-storage-was-internals-achieving-consistency.aspx</link><pubDate>Tue, 13 Dec 2011 16:05:50 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:40354</guid><dc:creator>BuckWoody</dc:creator><description>&lt;p&gt;Windows Azure Storage has three primary components - a Queue, a Binary Large Object (BLOB) store (two types of these), and Table Storage. &lt;/p&gt;  &lt;p&gt;Storage of data on-premises is fairly well understood - but there components of it that you may not consider. When you move to a distributed architecture, certain factors should be taken into account, such as consistency. Consistency means that when you store a datum it should be available in the same bit format across the calling mechanism. In other words, if you store a picture with a certain name, whenever you call that name that particular picture should show up. That might sound obvious - but when you begin to scale horizontally, it’s a big consideration. Systems are spread out over multiple physical racks, which are further separated into separate “fault domains” each with its own power, networking and so on, and in Windows Azure, the storage is replicated to ensure high-availability. &lt;/p&gt;  &lt;p&gt;Some “cloud” systems relax the consistency target to allow for the highest speed throughput. This might allow inconsistent reads, meaning that the datum recorded in the naming system would be available yet, or that it might allow an older version of the datum to be read. In Windows Azure, we took the position that the consistency is of the highest importance. We achieved this through constructs such as the Location Service (LS), Stream, Partition and Front-End layers, and separate replication engines. Of key importance in a system that allows high consistency is in the naming and object access protocols - in fact, these turn out to be some of the most pivotal. &lt;/p&gt;  &lt;p&gt;Windows Azure Storage has a complex arrangement to ensure this high consistency. You can read some very deep internals &lt;a href="http://sigops.org/sosp/sosp11/current/2011-Cascais/printable/11-calder.pdf"&gt;here&lt;/a&gt;.&amp;#160; And a video of the talk held at an ACM conference is &lt;span style="font-family:'Calibri','sans-serif';font-size:11pt;mso-fareast-font-family:calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:ar-sa;"&gt;&lt;a href="http://www.youtube.com/watch?v=QnYdbQO0yj4"&gt;&lt;u&gt;&lt;font color="#0000ff"&gt;here&lt;/font&gt;&lt;/u&gt;&lt;/a&gt;. &lt;/span&gt;&lt;/p&gt;</description></item></channel></rss>