<?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 'T-SQL Tuesday'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=T-SQL+Tuesday&amp;orTags=0</link><description>Search results matching tag 'T-SQL Tuesday'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Part of the journey: failure</title><link>http://sqlblog.com/blogs/rob_farley/archive/2013/05/13/part-of-the-journey-failure.aspx</link><pubDate>Tue, 14 May 2013 00:09:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:49051</guid><dc:creator>rob_farley</dc:creator><description>&lt;p&gt;The topic for this month’s T-SQL Tuesday is about the journey. &lt;a href="http://wendyverse.blogspot.com/2013/05/its-time-for-t-sqltuesday-42-long-and.html" target="_blank"&gt;Wendy Pastrick’s choice&lt;/a&gt; (I’m hosting again next month!).&lt;a href="http://wendyverse.blogspot.com/2013/05/its-time-for-t-sqltuesday-42-long-and.html"&gt;&lt;img style="margin:5px;border:0px currentColor;padding-top:0px;padding-right:0px;padding-left:0px;float:right;display:inline;background-image:none;" title="TSQL2sDay150x150" border="0" alt="TSQL2sDay150x150" align="right" src="http://sqlblog.com/blogs/rob_farley/TSQL2sDay150x150_747207D3.jpg" width="170" height="170"&gt;&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;There are a lot of journeys. There are some that just keep going, and others that seem to finish (some in success; some in failure). Of course, many of the ones that finish end up being the start of new journeys, but sometimes they don’t need to continue – they just need closure. There are things that can be learned regardless of how things went, whether or not goals were reached, and whether or not there was failure.&lt;/p&gt;
  
&lt;p&gt;There’s been a few things recently to remind me of this...&lt;/p&gt;
  
&lt;p&gt;I visited a company recently who has put a video together promoting the idea of failure. It wasn’t asking that people fail, but said “Go ahead and fail,” because failure happens. They had been through a rough time, but were persisting and seeing things turn around.&lt;/p&gt;
  
&lt;p&gt;Just the other night, we saw &lt;a href="http://en.wikipedia.org/wiki/Chitty_Chitty_Bang_Bang_(musical)" target="_blank"&gt;the musical Chitty Chitty Bang Bang&lt;/a&gt; (you probably know &lt;a href="http://en.wikipedia.org/wiki/Chitty_Chitty_Bang_Bang_(film)" target="_blank"&gt;the movie&lt;/a&gt; – the &lt;a href="http://en.wikipedia.org/wiki/Ian_Fleming" target="_blank"&gt;Bond&lt;/a&gt;&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Cubby_Broccoli" target="_blank"&gt;film&lt;/a&gt; where Dick van Dyke stars as the guy with the &lt;a href="http://en.wikipedia.org/wiki/Chitty_Chitty_Bang_Bang_(car)" target="_blank"&gt;gadget-car&lt;/a&gt;, who takes on &lt;a href="http://www.imdb.com/name/nm0002085/" target="_blank"&gt;Goldfinger&lt;/a&gt; and falls for the &lt;a href="http://en.wikipedia.org/wiki/Truly_Scrumptious" target="_blank"&gt;girl with the inappropriate name&lt;/a&gt;). Anyway, there’s a brilliant song in that called “&lt;a href="http://www.youtube.com/watch?v=GND10sWq0n0" target="_blank"&gt;The Roses of Success&lt;/a&gt;” (YouTube link there). It has the same sentiment – “…from the ashes of disaster grow the roses of success!”&lt;/p&gt;
  
&lt;p&gt;A few years ago, my kids started saying “FAIL!” when someone did something wrong. I can’t say I liked the insult. Far worse would’ve been “DIDN’T TRY!” It would be very easy to just stay in bed and ‘avoid failure’ that way, but anyone who fails has at least done something. To fail, you must at least be active.&lt;/p&gt;
  
&lt;p&gt;I talk to a lot of people about Microsoft Certification, particularly people who have failed an exam. I tell everyone (not just those who have failed before) to try the exams before they feel they’re ready for them, . What’s the worst that can happen? Worst case, they don’t pass. But how is that a bad thing? It might feel less than brilliant (I know, it’s happened to me before), but it gives an opportunity to target the weak areas before having a subsequent attempt. It doesn’t matter how many attempts it takes to get a passing score – the wrong option would be to give up. Studying can be excellent, but not to the point of causing extra stress.&lt;/p&gt;
  
&lt;p&gt;There are things in life we do easily, and there are things that we struggle with. I know there’s a bunch of stuff in my own life that falls into both categories. I don’t want this post to be a list of the things that I’m not doing well – I simply want to point out that I want to keep trying. &lt;/p&gt;
  
&lt;p&gt;With God’s help, I can improve in the areas in which I’m not excelling, and start to smell the roses of success.&lt;/p&gt;</description></item><item><title>T-SQL Tuesday #41 - Presenting and Loving it!</title><link>http://sqlblog.com/blogs/allen_white/archive/2013/04/09/t-sql-tuesday-41-presenting-and-loving-it.aspx</link><pubDate>Tue, 09 Apr 2013 15:56:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:48592</guid><dc:creator>AllenMWhite</dc:creator><description>&lt;p&gt;For this &lt;a href="http://www.bobpusateri.com/archive/2013/04/invitation-to-t-sql-tuesday-41-presenting-and-loving-it/"&gt;&lt;img src="http://img.bobpusateri.com/bc/2010/06/TSQL2sDay150x150.jpg" alt="T-SQL Tuesday"&gt;T-SQL Tuesday&lt;/a&gt; Bob Pusateri asked us to share how we came to love presenting.&lt;/p&gt;
&lt;p&gt;Before I ever got involved in computing technology I had (and still have) a love for the theatre, specifically musical theatre.  When I was little the majority of albums (this was the 1950s, kids) we had were cast albums from Broadway shows my parents had seen at &lt;a href="http://en.wikipedia.org/wiki/Musicarnival"&gt;Musicarnival&lt;/a&gt;.  I performed in shows all through school, and was a Theatre Major at Kent State University before I realized I needed to make a living.&lt;/p&gt;
&lt;p&gt;It was this love of "performing" that had employers sending me to the trade shows to talk with customers. I wasn't the typical programmer, I could talk with people, even people I didn't know!  One company was so impressed in my performance when I'd played Harold Hill in the show &lt;a href="http://en.wikipedia.org/wiki/The_Music_Man"&gt;&lt;i&gt;The Music Man&lt;/i&gt;&lt;/a&gt; that they made me a salesman.  That failed miserably.&lt;/p&gt;
&lt;p&gt;About eight years ago I started attending meetings of the Cleveland SQL Server group, at the Microsoft office in Independence, Ohio.  As people had questions I'd pipe up and answer when I could, and as they needed someone to present I offered to put together my materials as a presentation.  The first few times were a bit rough - ok, they were very rough - but the group was gracious and I learned to organize the material better.  In addition to the user group presentations I'd been giving training presentations to the staff at work, getting them to understand SQL Server better to make my job as the DBA easier.  This helped me develop my skills a lot.&lt;/p&gt;
&lt;p&gt;I was first selected to speak at the PASS Summit in 2006, and I presented a session on SMO (Server Management Objects) and my demos all used Visual Basic.  After the presentation a number of people came up to me and said they were administrators and weren't allowed to have Visual Studio on their desktop.  PowerShell had just been introduced and I adjusted my material to use PowerShell.&lt;/p&gt;
&lt;p&gt;Also in 2006 I became a Microsoft Certified Trainer (MCT).  In teaching the official Microsoft courses I learned how to work with material I hadn't created myself, which then helped me build better presentations of my own material.  I also learned that having to teach material forced me to learn it better myself.  Someone will always ask questions about an aspect of the topic I'd never encountered.  I found the best way to learn any topic is to teach it.&lt;/p&gt;
&lt;p&gt;In the course of events I became the leader of the &lt;a href="http://www.ohionorthsqlserverug.org/"&gt;Ohio North SQL Server Users Group&lt;/a&gt; and at each meeting I ask everyone there to think about putting together a presentation for the group, so we can learn from them, and they can learn it better.  We've got a great group of people who now present not just at our group but at others in the area and at SQL Saturdays and even the PASS Summit as well!  I can't tell you how pleased I am at how many from our group are regular presenters in the SQL Server community now. These people include Erin Stellato ( &lt;a href="http://www.sqlskills.com/blogs/erin/" title="Erin's blog"&gt;b&lt;/a&gt; | &lt;a href="http://www.twitter.com/erinstellato" title="Erin on Twitter"&gt;t&lt;/a&gt; ), Sarah Dutkiewicz ( &lt;a href="http://codinggeekette.com/" title="Sarah's blog"&gt;b&lt;/a&gt; | &lt;a href="http://www.twitter.com/sadukie" title="Sarah on Twitter"&gt;t&lt;/a&gt; ), Brian Davis ( &lt;a href="http://blogs.lessthandot.com/index.php/All/?disp=authdir&amp;amp;author=638" title="Brian's blog"&gt;b&lt;/a&gt; | &lt;a href="http://www.twitter.com/brian78" title="Brian on Twitter"&gt;t&lt;/a&gt; ), Adam Belebczuk ( &lt;a href="http://www.sqldiablo.com/" title="Adam's blog"&gt;b&lt;/a&gt; | &lt;a href="http://www.twitter.com/SQLDiablo" title="Adam on Twitter"&gt;t&lt;/a&gt; ), Craig Purnell ( &lt;a href="http://www.craigpurnell.com/" title="Craig's blog"&gt;b&lt;/a&gt; | &lt;a href="http://www.twitter.com/CraigPurnell" title="Craig on Twitter"&gt;t&lt;/a&gt; ), and Colleen Morrow ( &lt;a href="http://colleenmorrow.com/" title="Colleen's blog"&gt;b&lt;/a&gt; | &lt;a href="http://www.twitter.com/ClevelandDBA" title="Colleen on Twitter"&gt;t&lt;/a&gt; ), but more are stepping up regularly, and for that I thank each one of them.&lt;/p&gt;
&lt;p&gt;Presenting is one of those magic activities in which everyone benefits. I'm fortunate that I have a natural inclination towards it, but love to see new people stepping up and sharing their experience and knowledge with the rest of the community.&lt;/p&gt;
&lt;p&gt;See you at the next event!&lt;/p&gt;
&lt;p&gt;Allen&lt;/p&gt;</description></item><item><title>Why I present</title><link>http://sqlblog.com/blogs/rob_farley/archive/2013/04/08/why-i-present.aspx</link><pubDate>Tue, 09 Apr 2013 00:09:13 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:48581</guid><dc:creator>rob_farley</dc:creator><description>&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/louis_davidson/archive/2013/04/08/why-we-write-3-an-interview-with-rob-farley.aspx" target="_blank"&gt;Louis Davidson just asked me why I write&lt;/a&gt;, and now &lt;a href="http://www.bobpusateri.com/" target="_blank"&gt;Bob Pusateri&lt;/a&gt; (&lt;a href="http://twitter.com/sqlbob" target="_blank"&gt;@sqlbob&lt;/a&gt;) is asking me &lt;a href="http://www.bobpusateri.com/archive/2013/04/invitation-to-t-sql-tuesday-41-presenting-and-loving-it/" target="_blank"&gt;why I present&lt;/a&gt;, which is his question for this month’s T-SQL Tuesday.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.bobpusateri.com/archive/2013/04/invitation-to-t-sql-tuesday-41-presenting-and-loving-it/" target="_blank"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:5px;padding-left:0px;padding-right:0px;display:inline;float:right;border-top:0px;border-right:0px;padding-top:0px;" title="TSQL2sDay150x150" border="0" alt="TSQL2sDay150x150" align="right" src="http://sqlblog.com/blogs/rob_farley/TSQL2sDay150x150_6DCF9167.jpg" width="170" height="170" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If you didn’t follow the link to see his actual question, you’ll need to know that he actually posed the question “How did you come to love presenting?”&lt;/p&gt;  &lt;p&gt;Well, sometimes I don’t, but on the whole, I have to admit that presenting is part of who I am, and I miss it if I’m not presenting. It’s why despite being a &lt;a href="http://www.sqlpass.org/AboutPASS/BoardofDirectors.aspx" target="_blank"&gt;PASS board member&lt;/a&gt; (that link will only seem relevant if you’re reading this while I’m still one) and having plenty of reason to NOT present at the PASS Summit in 2013, I’ve submitted the maximum number of abstracts for consideration. It’s why I want to be teaching more, both online and in the classroom, and so on.&lt;/p&gt;  &lt;p&gt;It’s not that I think I have anything important to say (although I do only ever teach / present on things that I think are important).&lt;/p&gt;  &lt;p&gt;It’s not that I think I’m good at presenting (my feedback scores beg to differ).&lt;/p&gt;  &lt;p&gt;It’s not that I’m comfortable presenting (I still get ridiculously nervous most of the time).&lt;/p&gt;  &lt;p&gt;I’m just addicted to it.&lt;/p&gt;  &lt;p&gt;It’s a drug – it really is.&lt;/p&gt;  &lt;p&gt;I spend my time walking around the room, or around the stage, explaining things to people, watching for those moments when the audience gets it, and... well, I’m addicted to it.&lt;/p&gt;  &lt;p&gt;If you watch &lt;a title="http://www.sqlbits.com/Sessions/Event5/Designing_for_simplification" href="http://www.sqlbits.com/Sessions/Event5/Designing_for_simplification"&gt;http://www.sqlbits.com/Sessions/Event5/Designing_for_simplification&lt;/a&gt;, you’ll see a few things. I was in Wales, and had started with the few words in Welsh that I know (but that’s been edited out – hopefully when I thought I was saying ‘hello’ I wasn’t actually insulting anyone). I nearly fell off the stage. I broke the microphone. I typed some things wrong in my queries. People complained that I didn’t say anything significant…&lt;/p&gt;  &lt;p&gt;But around 33:10 in, you hear the audience almost start clapping. IN THE UK (where people don’t clap for presentations). It’s a moment where people see something they weren’t expecting, and (hopefully) realise the potential in what they’ve heard.&lt;/p&gt;  &lt;p&gt;Phil Nolan wrote nicely about me &lt;a href="http://philnolan.wordpress.com/2009/11/30/sqlbits-session-review-designing-for-simplification-rob-farley/" target="_blank"&gt;on his blog&lt;/a&gt;, and said “Those of you who know Rob Farley will know he’s a funny guy with an enormous armoury of shockingly bad jokes.” More importantly though, he wrote “His design tips challenged a number of our ideas and meant I took away many valuable techniques,” which helped me know why I present.&lt;/p&gt;  &lt;p&gt;…because it’s not about me, it’s about you. I present because at least one of the people in the audience will benefit from it. And that’s addictive.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitter.com/rob_farley" target="_blank"&gt;@rob_farley&lt;/a&gt;&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>Filegroups and Non-Clustered Indexes</title><link>http://sqlblog.com/blogs/rob_farley/archive/2013/03/11/filegroups-and-non-clustered-indexes.aspx</link><pubDate>Tue, 12 Mar 2013 00:20:11 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:48187</guid><dc:creator>rob_farley</dc:creator><description>&lt;p&gt;Let’s start with some basics and then jump in a bit deeper, for this post to go with the 40th &lt;a href="http://www.midnightdba.com/Jen/2013/03/invitation-to-t-sql-tuesday-040-file-and-filegroup-wisdom/" target="_blank"&gt;T-SQL Tuesday&lt;/a&gt;, hosted this month by &lt;a href="http://www.midnightdba.com/Jen/" target="_blank"&gt;Jen McCown&lt;/a&gt;. &lt;a href="http://www.midnightdba.com/Jen/2013/03/invitation-to-t-sql-tuesday-040-file-and-filegroup-wisdom/" target="_blank"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:5px;padding-left:0px;padding-right:0px;display:inline;float:right;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="TSQL2sDay150x150" border="0" alt="TSQL2sDay150x150" align="right" src="http://sqlblog.com/blogs/rob_farley/TSQL2sDay150x150_3F5FB646.jpg" width="170" height="170" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;SQL Server holds data, and that data is stored physically in files.&lt;/p&gt;  &lt;p&gt;Of course, in the database world we think of the data as living in tables&lt;a href="http://sqlblog.com/blogs/rob_farley/archive/2012/12/11/joins-in-single-table-queries.aspx" target="_blank"&gt;*&lt;/a&gt;, so naturally there must be some sort of mapping between the data in a table and the data in a file. This is where filegroups come in.&lt;/p&gt;  &lt;p&gt;When SQL objects are created within a database, there is an option to be able to tell the system where to actually store it. But this isn’t a file, it’s a filegroup. (If it were a file and the disk volume that the file was on filled up, we’d have big problems. Instead, we put it in a filegroup, and can add extra files (on different volumes if so desired) to that filegroup.) Objects are stored within filegroups. Filegroups are groups of files, although many database systems do end up with only a single file per filegroup.&lt;/p&gt;  &lt;p&gt;Filegroups end up providing a large amount of flexibility for the storage of data. Rarely accessed data can be put in filegroups that have files on cheaper (but probably slower) disk, while data that is heavily written can be put on disk that’s more appropriate for that, and so on. I’m sure you get the picture, and this is nothing overly thought-worthy.&lt;/p&gt;  &lt;p&gt;You may even have already considered the idea around partitioning data across filegroups, moving data of a certain age (but potentially even from the same table) onto a different filegroup, so that queries that use different parts of tables can benefit from having some data on faster disk. Lots of potential. :)&lt;/p&gt;  &lt;p&gt;Where it becomes interesting though, is when you start to consider the concept of non-clustered indexes.&lt;/p&gt;  &lt;p&gt;You see, while a clustered index (or heap) provides the structure to store the data across all the columns of a table (although I’m simplifying it a little in regard to LOB data), we use copies of some of that data (in non-clustered indexes) to optimise access to the data.&lt;/p&gt;  &lt;p&gt;So where are these copies stored? Many database people don’t even think about this kind of thing, in the same way that they often don’t think about including indexes in their database design. I’m going to figure you’re not in that boat though, because I probably know you, and you’re probably not one of those people.&lt;/p&gt;  &lt;p&gt;Most people like to have a default filegroup that is NOT the primary filegroup. It means that when they create new objects, those new objects get put in the default filegroup, not the primary one. But it’s not actually that simple.&lt;/p&gt;  &lt;p&gt;Let’s start by creating a database.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;CREATE DATABASE fg_testing;        &lt;br /&gt;GO         &lt;br /&gt;USE fg_testing;         &lt;br /&gt;GO         &lt;br /&gt;SELECT *         &lt;br /&gt;FROM sys.filegroups;         &lt;br /&gt;--Only one filegroup at the moment         &lt;br /&gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_39E11FD5.png" width="586" height="265" /&gt;&lt;/p&gt;  &lt;p&gt;Notice the column &lt;font face="Consolas"&gt;data_space_id&lt;/font&gt;. This is the column which identifies each filegroup. We’ll use it later.&lt;/p&gt;  &lt;p&gt;Let’s create a new filegroup and set it to be the default.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;ALTER DATABASE fg_testing ADD FILEGROUP FG2;        &lt;br /&gt;GO         &lt;br /&gt;SELECT *         &lt;br /&gt;FROM sys.filegroups;         &lt;br /&gt;GO&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_2FCC7EAA.png" width="567" height="206" /&gt;&lt;/p&gt;  &lt;p&gt;Cool – data_space_id 2 is created.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;ALTER DATABASE fg_testing MODIFY FILEGROUP FG2 DEFAULT;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_7ADF796C.png" width="564" height="105" /&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;I think this is a shame – but I guess it’s fair enough. We have to have a file in the filegroup before we can make it the default. That’s easy enough though, and probably what we’d be wanting to do before too long anyway.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;ALTER DATABASE fg_testing ADD FILE ( NAME = N'file2', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\DATA\fg_testing_file2.ndf') TO FILEGROUP FG2;        &lt;br /&gt;GO         &lt;br /&gt;ALTER DATABASE fg_testing MODIFY FILEGROUP FG2 DEFAULT;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_6A8401B3.png" width="770" height="162" /&gt;&lt;/p&gt;  &lt;p&gt;(I’m doing this on my laptop, which only has one physical drive – on a server it’d go somewhere more sensible of course)&lt;/p&gt;  &lt;p&gt;Now let’s add another filegroup. This is going to be for some data, but I don’t want it to be my default.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;ALTER DATABASE fg_testing ADD FILEGROUP FG3;        &lt;br /&gt;GO         &lt;br /&gt;ALTER DATABASE fg_testing ADD FILE ( NAME = N'file3', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\DATA\fg_testing_file3.ndf') TO FILEGROUP FG3;&lt;/font&gt;       &lt;br /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_07A9A9BE.png" width="731" height="186" /&gt;&lt;/p&gt;  &lt;p&gt;Now, I want to create an object on FG3, which I’m going to pretend is my slower disk.&lt;/p&gt;  &lt;p&gt;Once created, I’m looking in sys.objects to confirm which filegroup the table is in, but there’s no information there. Remember that a table is only metadata, and the things that matter are the indexes/heaps that are on it. Checking in sys.indexes shows me that indeed, it’s in data_space_id 3.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;CREATE TABLE dbo.OrderDates (OrderDate date PRIMARY KEY, NumOrders int NOT NULL DEFAULT 0) ON FG3;        &lt;br /&gt;GO         &lt;br /&gt;SELECT *         &lt;br /&gt;FROM sys.objects         &lt;br /&gt;WHERE object_id = OBJECT_ID('dbo.OrderDates');         &lt;br /&gt;GO         &lt;br /&gt;SELECT *         &lt;br /&gt;FROM sys.indexes         &lt;br /&gt;WHERE object_id = OBJECT_ID('dbo.OrderDates');         &lt;br /&gt;GO&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_798ABAC0.png" width="1063" height="449" /&gt;&lt;/p&gt;  &lt;p&gt;For completeness’ sake, I’m going to put some data in there, using a query &lt;a href="http://sqlblog.com/blogs/rob_farley/archive/2013/03/11/a-top-query.aspx" target="_blank"&gt;that I blogged about yesterday&lt;/a&gt;.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;INSERT dbo.OrderDates (OrderDate, NumOrders)        &lt;br /&gt;SELECT TOP (DATEDIFF(DAY,'20010101','20130312'))         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DATEADD(day,ROW_NUMBER() OVER (ORDER BY (SELECT 1))-1,'20010101') AS OrderDate,         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ABS(CHECKSUM(NEWID())) % 100 as NumOrders         &lt;br /&gt;FROM master.dbo.spt_values t1 CROSS JOIN master.dbo.spt_values t2         &lt;br /&gt;ORDER BY ROW_NUMBER() OVER (ORDER BY (SELECT 1))         &lt;br /&gt;GO&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_461ED197.png" width="796" height="235" /&gt;&lt;/p&gt;  &lt;p&gt;But the whole point of this was to see what happens with the non-clustered index, which I want to be on recent data only (ie, filtered), and I want it to be in the DEFAULT filegroup.&lt;/p&gt;  &lt;p&gt;As I want it in the default group, I won’t specify a filegroup for the index.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;CREATE INDEX ixRecentData ON dbo.OrderDates (OrderDate)        &lt;br /&gt;INCLUDE (NumOrders)         &lt;br /&gt;WHERE OrderDate &amp;gt;= '20130101';         &lt;br /&gt;GO         &lt;br /&gt;SELECT *         &lt;br /&gt;FROM sys.indexes         &lt;br /&gt;WHERE object_id = OBJECT_ID('dbo.OrderDates');&lt;/font&gt;       &lt;br /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_698B502F.png" width="968" height="333" /&gt;&lt;/p&gt;  &lt;p&gt;But look! It’s put the non-clustered index in the same filegroup as the clustered index. This isn’t what I wanted. In fact, it’s almost never what I’d want, because even if the disk performance is identical, it can be nice to have transactions which update both the clustered and non-clustered indexes using different disks.&lt;/p&gt;  &lt;p&gt;Instead, we have to specify it explicitly to tell it to use the filegroup we want.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;DROP INDEX ixRecentData ON dbo.OrderDates        &lt;br /&gt;GO         &lt;br /&gt;CREATE INDEX ixRecentData ON dbo.OrderDates (OrderDate)         &lt;br /&gt;INCLUDE (NumOrders)         &lt;br /&gt;WHERE OrderDate &amp;gt;= '20130101'         &lt;br /&gt;ON FG2;         &lt;br /&gt;GO         &lt;br /&gt;SELECT *         &lt;br /&gt;FROM sys.indexes         &lt;br /&gt;WHERE object_id = OBJECT_ID('dbo.OrderDates');&lt;/font&gt;       &lt;br /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_5E321625.png" width="902" height="386" /&gt;&lt;/p&gt;  &lt;p&gt;It’s a shame to have to be so explicit with these things, but when you create non-clustered indexes, you really should think about which filegroup they’re going onto, because they may well not go onto the default one as you might expect.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitter.com/rob_farley" target="_blank"&gt;@rob_farley&lt;/a&gt;&lt;/p&gt;</description></item><item><title>T-SQL Tuesday #39: Managing your SQL Server Services with PowerShell</title><link>http://sqlblog.com/blogs/allen_white/archive/2013/02/12/t-sql-tuesday-39-managing-your-sql-server-services-with-powershell.aspx</link><pubDate>Tue, 12 Feb 2013 18:09:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:47673</guid><dc:creator>AllenMWhite</dc:creator><description>
&lt;p&gt;&lt;a href="http://blog.waynesheffield.com/wayne/archive/2013/02/invitation-for-t-sql-tuesday-39-can-you-shell-what-the-posh-is-cooking/"&gt;&lt;img src="http://blog.waynesheffield.com/wayne/wp-content/uploads/2012/04/TSQL2sDay150x150.jpg" alt="T-SQL Tuesday"&gt;This T-SQL Tuesday&lt;/a&gt; is about using PowerShell to do something with SQL Server.  Now, if you've read any of my blog posts you probably know I've been using PowerShell to do things with SQL Server for a while now, but I'm glad Wayne decided on this topic for his T-SQL Tuesday topic, because everyone has different ways to use PowerShell, and you can learn from all of them, as I do.&lt;/p&gt;

&lt;p&gt;(When I started to write this post I'd intended to share how I convert a PerfMon binary log file into SQL Server data for baseline analysis, but found I'd already done that &lt;a href="http://sqlblog.com/blogs/allen_white/archive/2012/03/03/load-perfmon-log-data-into-sql-server-with-powershell.aspx"&gt;here&lt;/a&gt;. Then, I thought I'd share how I save SQL Agent jobs and move them to another server, but did &lt;a href="http://sqlblog.com/blogs/allen_white/archive/2012/05/02/script-and-migrate-agent-jobs-between-servers-using-powershell.aspx"&gt;that one&lt;/a&gt;, too!)&lt;/p&gt;

&lt;p&gt;One of the interesting aspects of SMO (Server Management Objects) is the Managed Computer object.  It doesn't get a lot of attention because, well, that goes to the SQL Server instance and the various database objects.  Administrators, though, need to pay attention to managing the instance itself.  SQL Server 2008 introduced the Configuration Manager, a GUI application that allows administrators to view the SQL Server services installed, including their current state, the service account they use, etc.  It also allows them to manage the external access to the instances via the network protocols supported, the TCP/IP ports, etc.&lt;/p&gt;

&lt;p&gt;Here's a diagram of the Managed Computer object:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cache.nebula.phx3.secureserver.net/obj/NTc2MjgwQzY3MDEwQzkxM0JBMDQ6NmY4YWVlZjU5MDRkNTUyZjg0YmM5MDE0Njc5ZTI2MmM=?u=446abbd5-9565-4e48-9bde-723335ef117f" alt="Managed Computer Object"&gt;&lt;/p&gt;

&lt;p&gt;Now, if you're familiar with the Configuration Manager you should see some parallels there, and that makes sense, because these objects are the ones Configuration Manager is working with.&lt;/p&gt;

&lt;p&gt;Let's say it's time for you to change the service account and password for your SQL Server instance.  Using this model, we have our guide.  We need to create a new ManagedComputer object, connect to the server, connect to the service, use the SetServiceAccount() method to set the new values, then restart the service.  In this example I'll also restart the Agent service since I'm resetting the SQL Server instance service account.&lt;/p&gt;

&lt;pre&gt;[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement") | Out-Null
$mc = new-object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer localhost
$sqlinst = $mc.Services['MSSQLSERVER']
$sqlagnt = $mc.Services['SQLSERVERAGENT']
$sqlinst.SetServiceAccount('TESTDOMAIN\AlternateAcct','L44HhRMeF25UDvQeJTj5UqyE')
$sqlinst.Alter()
$sqlinst.Stop()
start-sleep -s 10
$sqlinst.Start()
$sqlagnt.Start()
&lt;/pre&gt;
&lt;p&gt;Let's say I just want to see the services on my local instance, like I do in Configuration Manager. Again, that's pretty easy.&lt;/p&gt;

&lt;pre&gt;[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement") | Out-Null
$mc = new-object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer localhost
$mc.Services | select Name, ServiceState, DisplayName, ServiceAccount | format-table
&lt;/pre&gt;
&lt;p&gt;There are times you'll need to work with the network protocols, and I've actually used the following code to change the IP port for an instance after an install, because it HAD to match a particular value.&lt;/p&gt;

&lt;pre&gt;$mc = new-object ('Microsoft.SqlServer.Management.Smo.WMI.ManagedComputer') localhost
$i=$mc.ServerInstances['MSSQLSERVER']
$p=$i.ServerProtocols['Tcp']
$ip=$p.IPAddresses['IPAll']
$ip.IPAddressProperties['TcpDynamicPorts'].Value = '1099'
$p.Alter()
&lt;/pre&gt;
&lt;p&gt;Now, why is this important, if I can do all this in Configuration Manager? Well, SQL Server 2012 supports installation on Windows Server Core, and there's no GUI on a Core server, so this becomes the best way to access the objects you normally manage with Configuration Manager.  More importantly, it allows you to build a set of scripts to "just handle" any number of problems, without trying to remember what submenu gives you access to what property to change to solve your problem.&lt;/p&gt;

&lt;p&gt;Good luck, and thanks, Wayne, for hosting this month's T-SQL Tuesday!&lt;/p&gt;

&lt;p&gt;Allen&lt;/p&gt;</description></item><item><title>Behind the scenes of PowerShell and SQL</title><link>http://sqlblog.com/blogs/rob_farley/archive/2013/02/11/behind-the-scenes-of-powershell-and-sql.aspx</link><pubDate>Tue, 12 Feb 2013 00:11:46 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:47649</guid><dc:creator>rob_farley</dc:creator><description>&lt;p&gt;Every year, PowerShell increases its stranglehold on the Windows Server system and the applications that run upon it – with good reason too. Its consistent mechanisms for interaction between its scripting interface and the underlying systems make it easy for people to feel comfortable, and there is a discoverability that has been lacking in many other scripting environments.&lt;/p&gt;  &lt;p&gt;Of course, SQL Server hasn’t been overlooked at all, and it’s coming up to five years since the &lt;a href="https://msmvps.com/blogs/robfarley/archive/2008/03/04/sql-server-2008-powershell-snapin.aspx" target="_blank"&gt;SnapIns were made available&lt;/a&gt; (even longer since people started to &lt;a href="http://msmvps.com/blogs/robfarley/archive/2007/01/05/powershell-and-sql.aspx" target="_blank"&gt;dabble with SQL using PowerShell&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;But what’s going on behind the scenes? Does PowerShell present a threat to those amongst us who will always prefer T-SQL? Does PowerShell give us new options that are not available any other way? Well, let’s have a bit of a look, especially since this month’s T-SQL Tuesday (hosted by &lt;a href="http://blog.waynesheffield.com/wayne/archive/2013/02/invitation-for-t-sql-tuesday-39-can-you-shell-what-the-posh-is-cooking/" target="_blank"&gt;Wayne Sheffield&lt;/a&gt; who tweets as &lt;a href="http://twitter.com/DBAWayne" target="_blank"&gt;@DBAWayne&lt;/a&gt;) is on the topic of PowerShell.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.waynesheffield.com/wayne/archive/2013/02/invitation-for-t-sql-tuesday-39-can-you-shell-what-the-posh-is-cooking/" target="_blank"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:5px;padding-left:0px;padding-right:0px;display:inline;float:right;border-top:0px;border-right:0px;padding-top:0px;" title="TSQL2sDay150x150" border="0" alt="TSQL2sDay150x150" align="right" src="http://sqlblog.com/blogs/rob_farley/TSQL2sDay150x150_41BF631A.jpg" width="170" height="170" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So we know PowerShell is useful. However we spin it up, we can quickly jump into writing commands, whether it be interacting with WMI, hooking into some .Net assembly we’ve loaded up, or simply browsing the file system. I’ve developed a tendency to use it to start whichever SQL instances I’m needing for the day – by default I have all of them turned off, since I don’t know which one I’ll be wanting most.&lt;/p&gt;  &lt;p&gt;If we’re going to be interacting with SQL, then it’s easiest to either load up the SQLPS environment directly (there’s a PowerShell shortcut within Management Studio), or else (as I do), start a PowerShell window with the Snapin loaded. I prefer this later option, as the SQLPS environment is a slightly cut-back version of PowerShell. But either way – the stuff I’ll continue on with is essentially the same whichever environment you use.&lt;/p&gt;  &lt;p&gt;If you’ve talked about SQL with me long enough, you’ll have come across the fact that I often use SQL Profiler when I’m curious about where to find information. My former colleague &lt;a href="http://www.jimmcleod.net" target="_blank"&gt;Jim McLeod&lt;/a&gt; (&lt;a href="http://twitter.com/jim_mcleod" target="_blank"&gt;@Jim_McLeod&lt;/a&gt;) blogged &lt;a href="http://www.jimmcleod.net/blog/index.php/2012/08/14/t-sql-tuesday-33-trick-shots/" target="_blank"&gt;about this a few months ago&lt;/a&gt;, with an example that I remember looking through with him four or five years ago. It’s a great technique that works on all kinds of things, even across different versions of SQL Server. It also adds as a terrific reminder that Management Studio is not a special application, it simply knows how to ask for the pieces of information that it shows.&lt;/p&gt;  &lt;p&gt;But PowerShell (or SMO, for that matter), that’s in the .Net world. Surely that would be able to bypass the clunky T-SQL stuff that Management Studio does... I mean, Management Studio has to be flexible enough to work across remote servers, talking through firewalls that only allow T-SQL interfaces. Surely PowerShell has access to a deeper magic.&lt;/p&gt;  &lt;p&gt;Well, no. PowerShell still lets you talk to remote servers, and ends up using the same methods.&lt;/p&gt;  &lt;p&gt;Let’s prove it.&lt;/p&gt;  &lt;p&gt;Spin up Profiler, and start a trace against your favourite instance. I like to watch for SQL:BatchCompleted, SP:StmtCompleted and RPC:Completed events when doing this kind of thing. I’m using an instance that isn’t doing anything else, but you could apply a ColumnFilter to filter the events to things with an ApplicationName starting with SQLPS if you prefer.&lt;/p&gt;  &lt;p&gt;With that running, I jump into PowerShell and do something like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;PS SQLSERVER:\sql\localhost\sql2008r2&amp;gt; dir Databases | ft name&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This lists the names of the databases on my SQL2008R2 instances. You don’t need to see the results, you can imagine them for yourself.&lt;/p&gt;  &lt;p&gt;If PowerShell were using some secret interface, it’s unlikely we’d see something in Profiler. But it’s not, and we see a bunch of stuff.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_56ED68C2.png" width="672" height="468" /&gt;&lt;/p&gt;  &lt;p&gt;We see a bunch of Remote Procedure Calls, each with a Stored Procedure Statement Completed event showing the same information. And look – we see queries against master.sys.databases, asking for the name of each of the databases, passing in the name as a parameter. Brilliant! Notice just a bit earlier though, there’s a SQL:BatchCompleted call. This means that a query has been passed in directly. It’s this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;SELECT       &lt;br /&gt;CAST(        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; serverproperty(N'Servername')        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AS sysname) AS [Server_Name],        &lt;br /&gt;dtb.name AS [Name]        &lt;br /&gt;FROM        &lt;br /&gt;master.sys.databases AS dtb        &lt;br /&gt;WHERE        &lt;br /&gt;(CAST(case when dtb.name in ('master','model','msdb','tempdb') then 1 else dtb.is_distributor end AS bit)=0)        &lt;br /&gt;ORDER BY        &lt;br /&gt;[Name] ASC&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_3EB9D89A.png" width="646" height="432" /&gt;&lt;/p&gt;    &lt;p&gt;So it grabs the list of database names first, and then makes extra calls to be able to fetch the list of names again, one by one.&lt;/p&gt;  &lt;p&gt;The reason why it’s grabbing the list of names one by one isn’t because it’s stupid and is asking to be ridiculed. It’s because we've asked to see that property, and I guess the PowerShell people figured that no matter what property you ask for, it’ll go and fetch it to show you.&lt;/p&gt;  &lt;p&gt;When I asked for the CompatibilityLevel property instead, I got some different rows thrown in. Interestingly though, it still asked for the name each time.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_3862DC3F.png" width="635" height="437" /&gt;&lt;/p&gt;  &lt;p&gt;Also interestingly, when I asked for the CompatibilityLevel a subsequent time, the calls for “SELECT dtb.compatibility_level…” weren’t in there. They’d been cached by the PowerShell environment – important to note if you ever come across PowerShell giving you old values.&lt;/p&gt;  &lt;p&gt;So what about asking something more interesting? Let’s try asking about the IndexSpaceUsage in AdventureWorks.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;PS SQLSERVER:\sql\localhost\sql2008r2&amp;gt; gi Databases\AdventureWorks | ft IndexSpaceUsage&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The result tells me it’s 62576. Yeah, but today I’m not interested in that, just what happened in the trace.&lt;/p&gt;  &lt;p&gt;Four entries. An SP:StmtCompleted with matching RPC:Completed, and two SQL:BatchCompleted.&lt;/p&gt;  &lt;p&gt;The SP:StmtCompleted and RPC:Completed were this statement, passing in the parameter value ‘AdventureWorks’. Clearly incredibly informative.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;SELECT       &lt;br /&gt;CAST(0 AS float) AS [IndexSpaceUsage],        &lt;br /&gt;dtb.name AS [DatabaseName]        &lt;br /&gt;FROM        &lt;br /&gt;master.sys.databases AS dtb        &lt;br /&gt;WHERE        &lt;br /&gt;(dtb.name=@_msparam_0)&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is getting the value zero. Wow. Brilliant stuff.&lt;/p&gt;  &lt;p&gt;The last entry – the second of the two SQL:BatchCompleted events is:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;select convert(float,low/1024.) from master.dbo.spt_values where number = 1 and type = 'E'&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If you run this in Management Studio, you’ll discover it gives the value 8. Ok.&lt;/p&gt;  &lt;p&gt;The other entry is more interesting.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;use [AdventureWorks]       &lt;br /&gt;SELECT        &lt;br /&gt;SUM(CASE WHEN a.type &amp;lt;&amp;gt; 1 THEN a.used_pages WHEN p.index_id &amp;lt; 2 THEN a.data_pages ELSE 0 END) AS [DataSpaceUsage],        &lt;br /&gt;SUM(a.used_pages) AS [IndexSpaceTotal]        &lt;br /&gt;FROM        &lt;br /&gt;sys.allocation_units AS a INNER JOIN sys.partitions AS p ON (a.type = 2 AND p.partition_id = a.container_id) OR (a.type IN (1,3) AND p.hobt_id = a.container_id)&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is more like it! We run this in Management Studio, and we see two values. DataSpaceUsage is 13682, IndexSpaceTotal is 21504. Neither are our value 62576. But we do have clues in the column names, and in that value 8 that came back too. We can easily deduce that it’s actually (IndexSpaceTotal-DataSpaceUsage)*8, and we have ourselves a nice little method for working out the IndexSpaceUsage ourselves now if we need it.&lt;/p&gt;  &lt;p&gt;Or we can just ask PowerShell next time as well.&lt;/p&gt;  &lt;p&gt;Incidentally – if you’re considering doing the MCM Lab exam some time, then you might find that a familiarity with PowerShell comes in really handy. I’m not saying there are PowerShell questions on the exam at all – I’m just suggesting that you may find that PowerShell becomes a really useful way of getting at some of the information that you’re looking for. If you’re stumbling around the list of DMVs trying to remember which one it is that stores some particular thing, remember that you might be able to get the data out more easily if you use PowerShell instead.&lt;/p&gt;  &lt;p&gt;So can we discover secret things about SQL from PowerShell? Are there things we can do in PowerShell that are impossible through other mechanisms? Hooks that let us break the rules even?&lt;/p&gt;  &lt;p&gt;Recently, Kendal van Dyke asked a question about this kind of thing on Twitter. He was wondering if you could have a default constraint on a column in a view. The reason for his wondering was that he saw a property on a view column in PowerShell that made him wonder. The answer is no though, and there’s a simple reason.&lt;/p&gt;  &lt;p&gt;PowerShell is a programmatic interface. It involves classes and property and methods. It does things row by row, which is why much of what you see in that trace feels amazingly pedantic – asking about things which shouldn’t have to be that complicated. The implication of this though, is that PowerShell reuses the concept of a column, regardless of whether this is a column in a table, a view, or anywhere else it decides to need a column. The fact that columns in tables have some extra properties isn’t enough to make this class re-use pointless. If we try to set a Default constraint for a column in a view though, we get an error, just like if we tried to do it any other way.&lt;/p&gt;  &lt;p&gt;The PowerShell I used was:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;$db = Get-Item SQLSERVER:\sql\localhost\sql2008r2\Databases\AdventureWorks       &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;$def = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Default –ArgumentList $db, &amp;quot;ViewDefault&amp;quot;       &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;$def.TextHeader = &amp;quot;CREATE DEFAULT ViewDefault AS&amp;quot;       &lt;br /&gt;$def.TextBody = &amp;quot;'ABC'&amp;quot;        &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;$def.Create()       &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;$def.BindToColumn(&amp;quot;vStateProvinceCountryRegion&amp;quot;,&amp;quot;StateProvinceCode&amp;quot;,&amp;quot;Person&amp;quot;)&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The code that ended up getting called was to the stored procedure &lt;em&gt;sp_bindefault&lt;/em&gt; (despite it being deprecated). Naturally, trying to execute this against a view column gives an error regardless of what wrappers you have put around it – PowerShell or not.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_125D061C.png" width="813" height="132" /&gt;&lt;/p&gt;  &lt;p&gt;So PowerShell is very useful, and it provides a handy way of getting to a lot of things that could be otherwise hard. But looking below the surface, it isn’t able to circumvent the basic restrictions of SQL Server, because it still ends up doing its work using T-SQL.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitter.com/rob_farley" target="_blank"&gt;@rob_farley&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Running goals</title><link>http://sqlblog.com/blogs/rob_farley/archive/2013/01/07/running-goals.aspx</link><pubDate>Tue, 08 Jan 2013 00:03:25 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:47061</guid><dc:creator>rob_farley</dc:creator><description>&lt;p&gt;I’m not big on New Year resolutions. I can’t say I respond particularly well to “everyone’s doing something, I should too” situations. Peer pressure can be useful at times, but I also find that it can make me even more stubborn.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://jasonbrimhall.info/2013/01/02/t-sql-tuesday-38-standing-firm/" target="_blank"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:5px;padding-left:0px;padding-right:0px;display:inline;float:right;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="TSQL2sDay150x150" border="0" alt="TSQL2sDay150x150" align="right" src="http://sqlblog.com/blogs/rob_farley/TSQL2sDay150x150_79C669C8.jpg" width="170" height="170" /&gt;&lt;/a&gt;So when Jason Brimhall chose the topic for &lt;a href="http://jasonbrimhall.info/2013/01/02/t-sql-tuesday-38-standing-firm/" target="_blank"&gt;this month’s T-SQL Tuesday&lt;/a&gt; as “standing firm”, considering the ideas of “resolve, resolution, resolute”, I scowled a little, and wondered what I’d write about. I considered writing about my &lt;a href="http://sqlblog.com/blogs/rob_farley/archive/2012/12/18/mcm-lab-exam-this-week.aspx" target="_blank"&gt;MCM journey&lt;/a&gt; (although &lt;a href="http://sqlblog.com/blogs/rob_farley/archive/2013/01/05/mcm-i-passed.aspx" target="_blank"&gt;that’s&lt;/a&gt; &lt;a href="http://lobsterpot.com.au/microsoft-certified-master-in-sql-server" target="_blank"&gt;over&lt;/a&gt; – &lt;a href="http://blogs.technet.com/b/themasterblog/archive/2012/10/05/current-sql-2008-mcms-take-note-you-are-automatically-granted-the-mcsm-data-platform-certification.aspx" target="_blank"&gt;for a few months&lt;/a&gt;), or thinking about some &lt;a href="http://lobsterpot.com.au/" target="_blank"&gt;business-related&lt;/a&gt; thing – but the closest I have to a resolution this year is related to &lt;a href="http://www.dailymile.com/people/robfarley" target="_blank"&gt;running&lt;/a&gt;. I get that it’s not about SQL, but it seems very related to various members of the SQL community. You know who you are – don’t make me list you.&lt;/p&gt;  &lt;p&gt;Many of you won’t know that this May (2013) will mark ten years since I had a nasty back injury. I don’t have a dramatic story to tell about it – it happened at work at the water cooler. I simply bent over wrong, and years of having a job where I sit down a lot, cycling (I used to cycle to work most days, every day when I was living in London), and being a little taller than most finally took its toll. Suddenly there was pain, and I ended up in hospital being told I might not get to walk again, and to expect to be in there until some time in July.&lt;/p&gt;  &lt;p&gt;Prayer got me out in ten days. &lt;/p&gt;  &lt;p&gt;But there were things I lost. I’ve never since been able to pick up my sons (they were five and three at the time). I’ve never been able to ride a bike (although I haven’t forgotten how). Until 2012, I’d been unable to run. I have chronic pain, and I’ve got used to it (which is annoying, but I’ve learned to tolerate it. That’s not always a good thing, like the time I had a badly inflamed appendix and nearly got sent home – although my pain tolerance did mean I could fly to Seattle a few days after the operation).&lt;/p&gt;  &lt;p&gt;In 2011, I started to walk more. I walked about eight miles one time just to see if I could. The pain level was higher, as expected, but I managed it. Later that year, I walked a half marathon in Portland, Oregon, just before the PASS Summit. I even beat one of the people in the group who was supposedly running (I felt bad and wanted to wait for him, but I think if I’d stopped I wouldn’t’ve been able to finish).&lt;/p&gt;  &lt;p&gt;I kept walking, but in June 2012, I talked to my physio about getting running back. He’d supported me through the walking, and knew that it wasn’t causing me too much bother any more. He got me on the treadmill, then onto grass, then onto the road. It hurt more, but I was surviving. Annoyingly, a cough I had developed into more and I ended up being sick for the best part of June-August, but I was running when I could, and I was surviving.&lt;/p&gt;  &lt;p&gt;In November, I didn’t just walk a half marathon, I ran it. Annoyingly I had tendinitis in my right knee, which meant I had acute pain almost the whole way around the San Francisco course. I didn’t stop running though, and although my pace dropped so much I could’ve walked most of it faster, I got to the end. Last month, December 2012, I agreed to do at least 15 minutes of cardio every day, and I managed it. I ran over 75 miles during the month, and I’m sure my fitness level is improving.&lt;/p&gt;  &lt;p&gt;So what’s in store for 2013 on the running scene?&lt;/p&gt;  &lt;p&gt;Well, I want to get a better time in a half marathon. That shouldn’t be hard – I just need to run one when I’m not injured.&lt;/p&gt;  &lt;p&gt;I wouldn’t mind trying a full marathon. I’ve joined the &lt;a href="http://sarrc.asn.au" target="_blank"&gt;South Australian Road Runners’ Club&lt;/a&gt;, and there are some marathons I could aim for during the year. There are also some trips to the US that I’ll be doing, and I could try to do one over there.&lt;/p&gt;  &lt;p&gt;I want to keep going with doing some cardio every day. My weight is dropping and I would like to get back to close what I was before my injury. I don’t expect to get under it – I’m not in my 20s any more – but I would like to get close. In the next few weeks I should get under 200lb again (90.7kg), and would like to be able to reach 86kg. The goal isn’t just to lose weight, rather to keep increasing the fitness level and see my back improve. Too many times in the past ten years I’ve had such bad times with my back that I’ve been unable to stand straight, or walk more than a few paces without stopping and holding onto something. On those days, I wouldn’t’ve been able to do any cardio at all, and I praise God massively for the quality of life I have when those times aren’t haunting me.&lt;/p&gt;  &lt;p&gt;I don’t know if I can manage to run a particular distance in 2013. If I could average the same as December, that would get me to 900 miles for the year. That should mean that 1000 could be possible, but 750 miles could be a more realistic goal. I’d still be thrilled to be able to achieve that.&lt;/p&gt;  &lt;p&gt;So if you follow me on Twitter and see &lt;a href="https://twitter.com/search/realtime?q=runmeter+from%3Arob_farley&amp;amp;src=typd" target="_blank"&gt;one of these tweets&lt;/a&gt;, feel free to hit reply and send me a message. While I’m running, every tweet that starts with @rob_farley will get read out to me by the &lt;a href="http://www.abvio.com/" target="_blank"&gt;Runmeter app&lt;/a&gt; on my phone. That’s really encouraging, and it helps me know that I have supporters. Thanks in advance, because you’ll be helping me be more resolute.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitter.com/rob_farley" target="_blank"&gt;@rob_farley&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;PS: If you’ve read all the way down to here, go and donate some money to the &lt;a href="http://pages.teamintraining.org/wa/wdw13/yrobel" target="_blank"&gt;Leukaemia &amp;amp; Lymphoma Society, supporting Yanni Robel&lt;/a&gt; who will run 39.3 miles this weekend. I can’t see myself trying that particular feat, but two years ago, &lt;a href="http://yannirobel.com/archive/2011/04/sql-hike/" target="_blank"&gt;Yanni wasn’t a runner either&lt;/a&gt;. Both she and her husband John are good friends of mine who have encouraged me immensely. So go donate some money now and help her reach her fundraising goal too. &lt;a title="http://pages.teamintraining.org/wa/wdw13/yrobel" href="http://pages.teamintraining.org/wa/wdw13/yrobel" target="_blank"&gt;http://pages.teamintraining.org/wa/wdw13/yrobel&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Joins in single-table queries</title><link>http://sqlblog.com/blogs/rob_farley/archive/2012/12/10/joins-in-single-table-queries.aspx</link><pubDate>Tue, 11 Dec 2012 00:05:17 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:46601</guid><dc:creator>rob_farley</dc:creator><description>&lt;p&gt;Tables are only metadata. They don’t store data.&lt;/p&gt;  &lt;p&gt;I’ve written &lt;a href="http://sqlblog.com/blogs/rob_farley/archive/2010/09/14/table-no-such-thing.aspx" target="_blank"&gt;something about this&lt;/a&gt; before, but I want to take a viewpoint of this idea around the topic of joins, especially since it’s the topic for T-SQL Tuesday this month. Hosted this time by &lt;a href="http://sqlity.net/en/1175/t-sql-tuesday-37-invite-to-join-me-in-a-month-of-joins/" target="_blank"&gt;Sebastian Meine&lt;/a&gt; (&lt;a href="http://twitter.com/sqlity" target="_blank"&gt;@sqlity&lt;/a&gt;), who has a whole series on joins this month. Good for him – it’s a great topic. &lt;a href="http://sqlity.net/en/1175/t-sql-tuesday-37-invite-to-join-me-in-a-month-of-joins/" target="_blank"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:5px;padding-left:0px;padding-right:0px;display:inline;float:right;border-top:0px;border-right:0px;padding-top:0px;" title="TSQL2sDay150x150" border="0" alt="TSQL2sDay150x150" align="right" src="http://sqlblog.com/blogs/rob_farley/TSQL2sDay150x150_1CEA56EB.jpg" width="170" height="170" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In that last post I discussed the fact that we write queries against tables, but that the engine turns it into a plan against indexes. My point wasn’t simply that a table is actually just a Clustered Index (or heap, which I consider just a special type of index), but that data access always happens against indexes – never tables – and we should be thinking about the indexes (specifically the non-clustered ones) when we write our queries.&lt;/p&gt;  &lt;p&gt;I described the scenario of looking up phone numbers, and how it never really occurs to us that there is a master list of phone numbers, because we think in terms of the useful non-clustered indexes that the phone companies provide us, but anyway – that’s not the point of this post.&lt;/p&gt;  &lt;p&gt;So a table is metadata. It stores information about the names of columns and their data types. Nullability, default values, constraints, triggers – these are all things that define the table, but the data isn’t stored in the table. The data that a table describes is stored in a heap or clustered index, but it goes further than this.&lt;/p&gt;  &lt;p&gt;All the useful data is going to live in non-clustered indexes. Remember this. It’s important. Stop thinking about tables, and start thinking about indexes.&lt;/p&gt;  &lt;p&gt;So let’s think about tables as indexes. This applies even in a world created by &lt;a href="http://www.lmgtfy.com/?q=someone+who's+bad+at+database+design" target="_blank"&gt;someone else&lt;/a&gt;, who doesn’t have the best indexes in mind for you.&lt;/p&gt;  &lt;p&gt;I’m sure you don’t need me to explain Covering Index bit – the fact that if you don’t have sufficient columns “included” in your index, your query plan will either have to do a Lookup, or else it’ll give up using your index and use one that does have everything it needs (even if that means scanning it). If you haven’t seen that before, drop me a line and I’ll run through it with you. Or go and read &lt;a href="http://msmvps.com/blogs/robfarley/archive/2008/10/12/doing-the-maths-to-understand-sql-optimiser-choices.aspx" target="_blank"&gt;a post I did a long while ago&lt;/a&gt; about the maths involved in that decision.&lt;/p&gt;  &lt;p&gt;So – what I’m going to tell you is that a Lookup is a join.&lt;/p&gt;  &lt;p&gt;When I run &lt;font face="Consolas"&gt;SELECT CustomerID FROM Sales.SalesOrderHeader WHERE SalesPersonID = 285; &lt;/font&gt;against the AdventureWorks2012 get the following plan:&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_31AC299E.png" width="470" height="226" /&gt;&lt;/p&gt;  &lt;p&gt;I’m sure you can see the join. Don’t look in the query, it’s not there. But you should be able to see the join in the plan. It’s an Inner Join, implemented by a Nested Loop. It’s pulling data in from the Index Seek, and joining that to the results of a Key Lookup.&lt;/p&gt;  &lt;p&gt;It clearly is – the QO wouldn’t call it that if it wasn’t really one. It behaves exactly like any other Nested Loop (Inner Join) operator, pulling rows from one side and putting a request in from the other. You wouldn’t have a problem accepting it as a join if the query were slightly different, such as &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;SELECT sod.OrderQty       &lt;br /&gt;FROM Sales.SalesOrderHeader AS soh        &lt;br /&gt;JOIN Sales.SalesOrderDetail as sod        &lt;br /&gt;on sod.SalesOrderID = soh.SalesOrderID        &lt;br /&gt;WHERE soh.SalesPersonID = 285;&lt;/font&gt;      &lt;br /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_5CA417A3.png" width="478" height="223" /&gt;&lt;/p&gt;  &lt;p&gt;Amazingly similar, of course. This one is an explicit join, the first example was just as much a join, even thought you didn’t actually ask for one.&lt;/p&gt;  &lt;p&gt;You need to consider this when you’re thinking about your queries.&lt;/p&gt;  &lt;p&gt;But it gets more interesting.&lt;/p&gt;  &lt;p&gt;Consider this query: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;SELECT SalesOrderID       &lt;br /&gt;FROM Sales.SalesOrderHeader        &lt;br /&gt;WHERE SalesPersonID = 276        &lt;br /&gt;AND CustomerID = 29522;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It doesn’t look like there’s a join here either, but look at the plan.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_3993A633.png" width="513" height="240" /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;That’s not some Lookup in action – that’s a proper Merge Join. The Query Optimizer has worked out that it can get the data it needs by looking in two separate indexes and then doing a Merge Join on the data that it gets. Both indexes used are ordered by the column that’s indexed (one on SalesPersonID, one on CustomerID), and then by the CIX key SalesOrderID. Just like when you seek in the phone book to Farley, the Farleys you have are ordered by FirstName, these seek operations return the data ordered by the next field. This order is SalesOrderID, even though you didn’t explicitly put that column in the index definition. The result is two datasets that are ordered by SalesOrderID, making them very mergeable. &lt;/p&gt;  &lt;p&gt;Another example is the simple query&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;SELECT CustomerID       &lt;br /&gt;FROM Sales.SalesOrderHeader        &lt;br /&gt;WHERE SalesPersonID = 276;&lt;/font&gt;      &lt;br /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/rob_farley/image_0191B250.png" width="514" height="245" /&gt;&lt;/p&gt;  &lt;p&gt;This one prefers a Hash Match to a standard lookup even! This isn’t just ordinary index intersection, this is something else again! Just like before, we could imagine it better with two whole tables, but we shouldn’t try to distinguish between joining two tables and joining two indexes.&lt;/p&gt;  &lt;p&gt;The Query Optimizer can see (using basic maths) that it’s worth doing these particular operations using these two less-than-ideal indexes (because of course, the best indexese would be on both columns – a composite such as (SalesPersonID, CustomerID – and it would have the SalesOrderID column as part of it as the CIX key still).&lt;/p&gt;  &lt;p&gt;You need to think like this too.&lt;/p&gt;  &lt;p&gt;Not in terms of excusing single-column indexes like the ones in AdventureWorks2012, but in terms of having a picture about how you’d like your queries to run. If you start to think about what data you need, where it’s coming from, and how it’s going to be used, then you will almost certainly write better queries. &lt;/p&gt;  &lt;p&gt;…and yes, this would include when you’re dealing with regular joins across multiples, not just against joins within single table queries.&lt;/p&gt;</description></item><item><title>T-SQL Tuesday : Reflections on the PASS Summit and our community</title><link>http://sqlblog.com/blogs/aaron_bertrand/archive/2012/11/13/t-sql-tuesday-reflections-on-the-pass-summit-and-our-community.aspx</link><pubDate>Tue, 13 Nov 2012 15:20:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:46142</guid><dc:creator>AaronBertrand</dc:creator><description>
&lt;p&gt;&lt;a target="_blank" href="http://chrisyatessql.wordpress.com/2012/11/05/t-sql-tuesday-36-sql-community-what-does-the-community-mean-to-you/"&gt;&lt;img align="left" style="margin-right:20px;" src="http://sqlblog.com/files/folders/36686/download.aspx"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Last week I attended the &lt;a target="_blank" href="http://www.sqlpass.org/summit/2012/AttendeeZone.aspx"&gt;PASS Summit&lt;/a&gt; in Seattle. I blogged from both keynotes (&lt;a target="_blank" href="http://sqlblog.com/blogs/aaron_bertrand/archive/2012/11/07/blogging-from-the-pass-summit-nov-7th-keynote.aspx"&gt;Keynote #1&lt;/a&gt; and &lt;a target="_blank" href="http://sqlblog.com/blogs/aaron_bertrand/archive/2012/11/08/blogging-from-the-pass-summit-nov-8th-keynote.aspx"&gt;Keynote #2&lt;/a&gt;), as well as the &lt;a target="_blank" href="http://sqlblog.com/blogs/aaron_bertrand/archive/2012/11/08/blogging-from-the-pass-summit-wit-luncheon.aspx"&gt;WIT Luncheon&lt;/a&gt; - which SQL Sentry sponsored.&lt;/p&gt;

&lt;p&gt;I had a fantastic time at the conference, even though these days I attend far fewer sessions that I used to. As a company, we were overwhelmed by the positive energy in the Expo Hall.&lt;/p&gt;

&lt;p&gt;I really liked the notebook idea, where board members were assigned notebooks to carry around and take ideas from attendees. I took full advantage when &lt;a target="_blank" href="http://www.sqlpass.org/AboutPASS/DouglasMcDowell.aspx"&gt;Douglas McDowell&lt;/a&gt; stopped by our booth. He had a good explanation for some of my questions/gripes, but definitely walked away with some work items. I think the whole "we are listening" message went over quite well, and PASS continues to demonstrate its commitment to improving the community.&lt;/p&gt;

&lt;p&gt;Highlights of the conference, for me, were chatting with Steve Dybing (an MVP lead from the past), attending a &lt;a target="_blank" href="http://sqlblog.com/blogs/paul_white/default.aspx"&gt;Paul White&lt;/a&gt; session, and talking briefly with both &lt;a target="_blank" href="http://blogs.msdn.com/b/conor_cunningham_msft/"&gt;Conor Cunningham&lt;/a&gt; (off-site) and &lt;a target="_blank" href="http://gsl.azurewebsites.net/People/dewitt.aspx"&gt;Dr. David DeWitt&lt;/a&gt; (on stage).&lt;/p&gt;

&lt;p&gt;&lt;a target="_blank" href="http://sqlblog.com/files/folders/46138/download.aspx"&gt;&lt;img style="border:1px solid black;" src="http://sqlblog.com/files/folders/46139/download.aspx"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;I had many other great conversations with friends and customers, new and old, far too many to mention. Which brings me to the point of the post: &lt;b&gt;community&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;I think we have a fantastic SQL Server community. Is it perfect? No. Do we all want to hang out together all the time? No. Like any family, there are the weird uncles that you just don't see eye-to-eye with on a few or even a lot of issues. And that's okay. Families are supposed to have disagreements, fallouts and other rough times. They make us stronger. And in a roundabout way, remind us that we're all here for each other.&lt;/p&gt;

&lt;p&gt;This stage of my career was launched on the backs of the SQL Server community, and I am very thankful for that. And I get the feeling, more and more every year, that folks attend the PASS Summit both for the technical content and, to an even greater degree, the people that are there.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item></channel></rss>