<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www2.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://www2.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>Plan Operator Tuesday round-up</title><link>http://www2.sqlblog.com/blogs/rob_farley/archive/2013/06/12/plan-operator-tuesday-round-up.aspx</link><pubDate>Wed, 12 Jun 2013 21:00:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:49654</guid><dc:creator>rob_farley</dc:creator><description>&lt;p&gt;Eighteen posts for &lt;a href="http://sqlblog.com/blogs/rob_farley/archive/2013/06/02/t-sql-tuesday-43-hello-operator.aspx" target="_blank" mce_href="http://sqlblog.com/blogs/rob_farley/archive/2013/06/02/t-sql-tuesday-43-hello-operator.aspx"&gt;T-SQL Tuesday #43 this month&lt;/a&gt;, discussing Plan Operators.&lt;/p&gt;
 
&lt;p&gt;I put them together and made the following clickable plan. It’s 1000px wide, so I hope you have a monitor wide enough.&lt;/p&gt;
 &lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" border="0" src="http://sqlblog.com/blogs/rob_farley/fakeplan_10657EC4.jpg" width="1002" height="500" useMap="#fakeplan_map"&gt; &lt;map id="_fakeplan_map" name="fakeplan_map"&gt;&lt;area title="" href="http://blog.waynesheffield.com/wayne/archive/2013/06/t-sql-tuesday-43-plan-operators/" shape="rect" alt="" coords="0,16,129,99" mce_href="http://blog.waynesheffield.com/wayne/archive/2013/06/t-sql-tuesday-43-plan-operators/"&gt;&lt;area title="" href="http://jasonbrimhall.info/2013/06/11/t-sql-tuesday-43-hello-operator/" shape="rect" alt="" coords="153,11,282,94" mce_href="http://jasonbrimhall.info/2013/06/11/t-sql-tuesday-43-hello-operator/"&gt;&lt;area title="" href="http://devjef.wordpress.com/2013/06/11/t-sql-tuesday-43-hello-operator/" shape="rect" alt="" coords="322,15,451,98" mce_href="http://devjef.wordpress.com/2013/06/11/t-sql-tuesday-43-hello-operator/"&gt;&lt;area title="" href="http://www.sqlballs.com/2013/06/t-sql-tuesday-43-crossing-streams.html" shape="rect" alt="" coords="495,16,624,99" mce_href="http://www.sqlballs.com/2013/06/t-sql-tuesday-43-crossing-streams.html"&gt;&lt;area title="" href="http://www.oliverasmus.com/2013/06/11/t-sql-tuesday-43-hello-operator/" shape="rect" alt="" coords="677,13,806,96" mce_href="http://www.oliverasmus.com/2013/06/11/t-sql-tuesday-43-hello-operator/"&gt;&lt;area title="" href="http://borishristov.com/blog/t-sql-tuesday-43-table-scan-in-action/" shape="rect" alt="" coords="855,13,984,96" mce_href="http://borishristov.com/blog/t-sql-tuesday-43-table-scan-in-action/"&gt;&lt;area title="" href="http://www.jasonstrate.com/2013/06/t-sql-tuesday-evil-plan-operators-tsql2sday/" shape="rect" alt="" coords="321,106,450,189" mce_href="http://www.jasonstrate.com/2013/06/t-sql-tuesday-evil-plan-operators-tsql2sday/"&gt;&lt;area title="" href="http://voiceofthedba.wordpress.com/2013/06/11/t-sql-tuesday-43hello-operator/" shape="rect" alt="" coords="495,109,624,192" mce_href="http://voiceofthedba.wordpress.com/2013/06/11/t-sql-tuesday-43hello-operator/"&gt;&lt;area title="" href="http://sqlblog.com/blogs/paul_white/archive/2013/06/11/hello-operator-my-switch-is-bored.aspx" shape="rect" alt="" coords="675,111,804,194" mce_href="http://sqlblog.com/blogs/paul_white/archive/2013/06/11/hello-operator-my-switch-is-bored.aspx"&gt;&lt;area title="" href="http://sqlblog.com/blogs/kalen_delaney/archive/2013/06/10/tsql-tuesday-what-kind-of-bookmark-are-you-using.aspx" shape="rect" alt="" coords="855,108,984,191" mce_href="http://sqlblog.com/blogs/kalen_delaney/archive/2013/06/10/tsql-tuesday-what-kind-of-bookmark-are-you-using.aspx"&gt;&lt;area title="" href="http://www.dbnewsfeed.com/2013/06/11/nested-loops-and-parallelism/" shape="rect" alt="" coords="321,208,450,291" mce_href="http://www.dbnewsfeed.com/2013/06/11/nested-loops-and-parallelism/"&gt;&lt;area title="" href="http://sqlblog.com/blogs/rob_farley/archive/2013/06/11/spooling-in-sql-execution-plans.aspx" shape="rect" alt="" coords="492,208,621,291" mce_href="http://sqlblog.com/blogs/rob_farley/archive/2013/06/11/spooling-in-sql-execution-plans.aspx"&gt;&lt;area title="" href="http://jonmorisissqlblog.blogspot.com/2013/06/scans-and-seeks.html" shape="rect" alt="" coords="678,210,807,293" mce_href="http://jonmorisissqlblog.blogspot.com/2013/06/scans-and-seeks.html"&gt;&lt;area title="" href="http://www.dataogre.com/2013/06/10/key-lookups-at-the-poker-table-tsql2sday/" shape="rect" alt="" coords="853,209,982,292" mce_href="http://www.dataogre.com/2013/06/10/key-lookups-at-the-poker-table-tsql2sday/"&gt;&lt;area title="" href="http://clarkcreations.net/blog/t-sql-tuesday-43-hello-operator/" shape="rect" alt="" coords="496,307,625,390" mce_href="http://clarkcreations.net/blog/t-sql-tuesday-43-hello-operator/"&gt;&lt;area title="" href="http://sqlity.net/en/1682/the-deceiving-seek-operator-tsql-tuesday-043-hello-operator/" shape="rect" alt="" coords="646,306,839,389" mce_href="http://sqlity.net/en/1682/the-deceiving-seek-operator-tsql-tuesday-043-hello-operator/"&gt;&lt;area title="" href="http://mickeystuewe.com/2013/06/11/t-sql-tuesday-43-give-me-a-key-lookup-operator-for-1200-please/" shape="rect" alt="" coords="856,307,985,390" mce_href="http://mickeystuewe.com/2013/06/11/t-sql-tuesday-43-give-me-a-key-lookup-operator-for-1200-please/"&gt;&lt;area title="" href="http://www.bidn.com/blogs/KathiKellenberger/sql-server/4372/hello-operator-key-lookup" shape="rect" alt="" coords="855,406,984,489" mce_href="http://www.bidn.com/blogs/KathiKellenberger/sql-server/4372/hello-operator-key-lookup"&gt;&lt;/map&gt;  
&lt;p&gt;Let me explain this plan for you (people’s names are the links to the articles on their blogs – the same links as in the plan above).&lt;/p&gt;
  
&lt;p&gt;It was clearly a SELECT statement. &lt;a href="http://blog.waynesheffield.com/wayne/archive/2013/06/t-sql-tuesday-43-plan-operators/" target="_blank" mce_href="http://blog.waynesheffield.com/wayne/archive/2013/06/t-sql-tuesday-43-plan-operators/"&gt;Wayne Sheffield&lt;/a&gt; (&lt;a href="http://twitter.com/dbawayne" target="_blank" mce_href="http://twitter.com/dbawayne"&gt;@dbawayne&lt;/a&gt;) wrote about that, so we start with a SELECT physical operator, leveraging the logical operator Wayne Sheffield.&lt;/p&gt;
  
&lt;p&gt;The SELECT operator calls the Paul White operator, discussed by &lt;a href="http://jasonbrimhall.info/2013/06/11/t-sql-tuesday-43-hello-operator/" target="_blank" mce_href="http://jasonbrimhall.info/2013/06/11/t-sql-tuesday-43-hello-operator/"&gt;Jason Brimhall&lt;/a&gt; (&lt;a href="http://twitter.com/sqlrnnr" target="_blank" mce_href="http://twitter.com/sqlrnnr"&gt;@sqlrnnr&lt;/a&gt;) in his post. The Paul White operator is quite remarkable, and can consume three streams of data. Let’s look at those streams.&lt;/p&gt;
  
&lt;p&gt;The first pulls data from a Table Scan – &lt;a href="http://borishristov.com/blog/t-sql-tuesday-43-table-scan-in-action/" target="_blank" mce_href="http://borishristov.com/blog/t-sql-tuesday-43-table-scan-in-action/"&gt;Boris Hristov&lt;/a&gt; (&lt;a href="http://twitter.com/borishristov" target="_blank" mce_href="http://twitter.com/borishristov"&gt;@borishristov&lt;/a&gt;)’s post – using parallel threads (&lt;a href="http://www.sqlballs.com/2013/06/t-sql-tuesday-43-crossing-streams.html" target="_blank" mce_href="http://www.sqlballs.com/2013/06/t-sql-tuesday-43-crossing-streams.html"&gt;Bradley Ball&lt;/a&gt; – &lt;a href="http://twitter.com/sqlballs" target="_blank" mce_href="http://twitter.com/sqlballs"&gt;@sqlballs&lt;/a&gt;) that pull the data eagerly through a Table Spool (&lt;a href="http://www.oliverasmus.com/2013/06/11/t-sql-tuesday-43-hello-operator/" target="_blank" mce_href="http://www.oliverasmus.com/2013/06/11/t-sql-tuesday-43-hello-operator/"&gt;Oliver Asmus&lt;/a&gt; – &lt;a href="http://twitter.com/oliverasmus" target="_blank" mce_href="http://twitter.com/oliverasmus"&gt;@oliverasmus&lt;/a&gt;). A scalar operation is also performed on it, thanks to &lt;a href="http://devjef.wordpress.com/2013/06/11/t-sql-tuesday-43-hello-operator/" target="_blank" mce_href="http://devjef.wordpress.com/2013/06/11/t-sql-tuesday-43-hello-operator/"&gt;Jeffrey Verheul&lt;/a&gt; (&lt;a href="http://twitter.com/devjef" target="_blank" mce_href="http://twitter.com/devjef"&gt;@devjef&lt;/a&gt;)’s Compute Scalar operator.&lt;/p&gt;
  
&lt;p&gt;The second stream of data applies Evil (I figured that must mean a procedural TVF, but could’ve been anything), courtesy of &lt;a href="http://www.jasonstrate.com/2013/06/t-sql-tuesday-evil-plan-operators-tsql2sday/" target="_blank" mce_href="http://www.jasonstrate.com/2013/06/t-sql-tuesday-evil-plan-operators-tsql2sday/"&gt;Jason Strate&lt;/a&gt; (&lt;a href="http://twitter.com/stratesql" target="_blank" mce_href="http://twitter.com/stratesql"&gt;@stratesql&lt;/a&gt;). It performs this Evil on the merging of parallel streams (&lt;a href="http://voiceofthedba.wordpress.com/2013/06/11/t-sql-tuesday-43hello-operator/" target="_blank" mce_href="http://voiceofthedba.wordpress.com/2013/06/11/t-sql-tuesday-43hello-operator/"&gt;Steve Jones&lt;/a&gt; – &lt;a href="http://twitter.com/way0utwest" target="_blank" mce_href="http://twitter.com/way0utwest"&gt;@way0utwest&lt;/a&gt;), which suck data out of a Switch (&lt;a href="http://sqlblog.com/blogs/paul_white/archive/2013/06/11/hello-operator-my-switch-is-bored.aspx" target="_blank" mce_href="http://sqlblog.com/blogs/paul_white/archive/2013/06/11/hello-operator-my-switch-is-bored.aspx"&gt;Paul White&lt;/a&gt; – &lt;a href="http://twitter.com/sql_kiwi" target="_blank" mce_href="http://twitter.com/sql_kiwi"&gt;@sql_kiwi&lt;/a&gt;). This Switch operator is consuming data from up to four lookups, thanks to &lt;a href="http://sqlblog.com/blogs/kalen_delaney/archive/2013/06/10/tsql-tuesday-what-kind-of-bookmark-are-you-using.aspx" target="_blank" mce_href="http://sqlblog.com/blogs/kalen_delaney/archive/2013/06/10/tsql-tuesday-what-kind-of-bookmark-are-you-using.aspx"&gt;Kalen Delaney&lt;/a&gt; (&lt;a href="http://twitter.com/sqlqueen" target="_blank" mce_href="http://twitter.com/sqlqueen"&gt;@sqlqueen&lt;/a&gt;), &lt;a href="http://www.dataogre.com/2013/06/10/key-lookups-at-the-poker-table-tsql2sday/" target="_blank" mce_href="http://www.dataogre.com/2013/06/10/key-lookups-at-the-poker-table-tsql2sday/"&gt;Rick Krueger&lt;/a&gt; (&lt;a href="http://twitter.com/dataogre" target="_blank" mce_href="http://twitter.com/dataogre"&gt;@dataogre&lt;/a&gt;), &lt;a href="http://mickeystuewe.com/2013/06/11/t-sql-tuesday-43-give-me-a-key-lookup-operator-for-1200-please/" target="_blank" mce_href="http://mickeystuewe.com/2013/06/11/t-sql-tuesday-43-give-me-a-key-lookup-operator-for-1200-please/"&gt;Mickey Stuewe&lt;/a&gt; (&lt;a href="http://twitter.com/sqlmickey" target="_blank" mce_href="http://twitter.com/sqlmickey"&gt;@sqlmickey&lt;/a&gt;) and &lt;a href="http://www.bidn.com/blogs/KathiKellenberger/sql-server/4372/hello-operator-key-lookup" target="_blank" mce_href="http://www.bidn.com/blogs/KathiKellenberger/sql-server/4372/hello-operator-key-lookup"&gt;Kathi Kellenberger&lt;/a&gt; (&lt;a href="http://twitter.com/auntkathi" target="_blank" mce_href="http://twitter.com/auntkathi"&gt;@auntkathi&lt;/a&gt;). Unfortunately Kathi’s name is a bit long and has been truncated, just like in real plans.&lt;/p&gt;
  
&lt;p&gt;The last stream performs a join of two others via a Nested Loop (&lt;a href="http://www.dbnewsfeed.com/2013/06/11/nested-loops-and-parallelism/" target="_blank" mce_href="http://www.dbnewsfeed.com/2013/06/11/nested-loops-and-parallelism/"&gt;Matan Yungman&lt;/a&gt; – &lt;a href="http://twitter.com/matanyungman" target="_blank" mce_href="http://twitter.com/matanyungman"&gt;@matanyungman&lt;/a&gt;). One pulls data from a Spool (&lt;a href="http://sqlblog.com/blogs/rob_farley/archive/2013/06/11/spooling-in-sql-execution-plans.aspx" target="_blank" mce_href="http://sqlblog.com/blogs/rob_farley/archive/2013/06/11/spooling-in-sql-execution-plans.aspx"&gt;my post&lt;/a&gt; – &lt;a href="http://twitter.com/rob_farley" target="_blank" mce_href="http://twitter.com/rob_farley"&gt;@rob_farley&lt;/a&gt;) populated from a Table Scan (&lt;a href="http://jonmorisissqlblog.blogspot.com/2013/06/scans-and-seeks.html" target="_blank" mce_href="http://jonmorisissqlblog.blogspot.com/2013/06/scans-and-seeks.html"&gt;Jon Morisi&lt;/a&gt;). The other applies a catchall operator (the catchall is because &lt;a href="http://clarkcreations.net/blog/t-sql-tuesday-43-hello-operator/" target="_blank" mce_href="http://clarkcreations.net/blog/t-sql-tuesday-43-hello-operator/"&gt;Tamera Clark&lt;/a&gt; (&lt;a href="http://twitter.com/tameraclark" target="_blank" mce_href="http://twitter.com/tameraclark"&gt;@tameraclark&lt;/a&gt;) didn’t specify any particular operator, and a catchall is what gets shown when SSMS doesn’t know what to show. Surprisingly, it’s showing the yellow one, which is about cursors. Hopefully that’s not what Tamera planned, but anyway...) to the output from an Index Seek operator (&lt;a href="http://sqlity.net/en/1682/the-deceiving-seek-operator-tsql-tuesday-043-hello-operator/" target="_blank" mce_href="http://sqlity.net/en/1682/the-deceiving-seek-operator-tsql-tuesday-043-hello-operator/"&gt;Sebastian Meine&lt;/a&gt; – &lt;a href="http://twitter.com/sqlity" target="_blank" mce_href="http://twitter.com/sqlity"&gt;@sqlity&lt;/a&gt;).&lt;/p&gt;
  
&lt;p&gt;Lastly, I think everyone put in 110% effort, so that’s what all the operators cost. That didn’t leave anything for me, unfortunately, but that’s okay. Also, because he decided to use the Paul White operator, Jason Brimhall gets 0%, and his 110% was given to Paul’s Switch operator post.&lt;/p&gt;
  
&lt;p&gt;I hope you’ve enjoyed this T-SQL Tuesday, and have learned something extra about Plan Operators. Keep your eye out for next month’s one by watching the Twitter Hashtag &lt;a href="http://twitter.com/search?q=%23tsql2sday" target="_blank" mce_href="http://twitter.com/search?q=%23tsql2sday"&gt;#tsql2sday&lt;/a&gt;, and why not contribute a post to the party? Big thanks to &lt;a href="http://sqlblog.com/blogs/adam_machanic" target="_blank" mce_href="http://sqlblog.com/blogs/adam_machanic"&gt;Adam Machanic&lt;/a&gt; as usual for starting all this.&lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://twitter.com/rob_farley" target="_blank" mce_href="http://twitter.com/rob_farley"&gt;@rob_farley&lt;/a&gt;&lt;/p&gt;</description></item><item><title>T-SQL Tuesday: What kind of Bookmark are you using?</title><link>http://www2.sqlblog.com/blogs/kalen_delaney/archive/2013/06/10/tsql-tuesday-what-kind-of-bookmark-are-you-using.aspx</link><pubDate>Tue, 11 Jun 2013 03:21:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:49537</guid><dc:creator>Kalen Delaney</dc:creator><description>&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/rob_farley/archive/2013/06/02/t-sql-tuesday-43-hello-operator.aspx"&gt;&lt;img width="150" height="150" title="TSQL2sDay150x150" align="right" alt="TSQL2sDay150x150" src="http://sqlblog.com/blogs/rob_farley/TSQL2sDay150x150_1B3B2D1E.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I’m glad there is no minimum length requirement for &lt;a href="http://sqlblog.com/blogs/rob_farley/archive/2013/06/02/t-sql-tuesday-43-hello-operator.aspx"&gt;T-SQL Tuesday blog posts&lt;/a&gt;, because this one will be short. I was in the classroom for almost 11 hours today, and I need to be back tomorrow morning at 7:30. &lt;/p&gt;  &lt;p&gt;Way long ago, back in SQL 2000 (or was it earlier?) when a query indicated that SQL Server was going to use a nonclustered index to get row pointers, and then look up those rows in the underlying table, the plan just had a very linear look to it. The operator that indicated going from the nonclustered leaf to the data row was called a ‘Bookmark Lookup’, and it just looked a simple, single operator. Those of us that did troubleshooting of query plans knew that it could hide a multitude of sins, but to many people it looked very innocuous. &lt;/p&gt;  &lt;p&gt;Then in the next version, that simple, single Bookmark Lookup Operator was replaced by something that looked like a JOIN! When I first saw query plans showing a JOIN when doing a nonclustered index lookup, I was almost distraught, but it turns out that was only because it was new and different. The more I thought about it, the more I realized it was a Good Thing. &lt;/p&gt;  &lt;p&gt;Some people might get confused because they think of a JOIN as an operation that finds matches rows between two tables. But in fact, a JOIN can be used to find matches between any two sets of rows. And in the case of a nonclustered index lookup, SQL Server is finding rows in the leaf level of a nonclustered index (the ones that meet your filter condition(s) ) , and then is finding the matching rows in the underlying table. Internally, this is a JOIN operation.&lt;/p&gt;  &lt;p&gt;But when we look at the plans, there are two different operators used to show the actual lookup into the underlying table.&lt;/p&gt;  &lt;p&gt;There is a RID Lookup, used when the table is a heap. The nonclustered index contains Row ID, or RID, values (composed of a File ID, a Page ID and a Slot/Row number on the page). This RID is then used to ‘match’ with rows in the underlying table that have the same RID.&lt;/p&gt;  &lt;p&gt;There is also a KEY Lookup, used when the table has a clustered index.&amp;nbsp; The leaf level of a nonclustered index contains pointers that are the key values for the rows being pointed to. So to find the matching rows in the table, SQL Server takes the clustered key value from the nonclustered index, and then searches for that value in the clustered index, following the clustered index from the root down to its leaf.&lt;/p&gt;  &lt;p&gt;Below are the two icons used for these operations. If I were to give you a quiz, and ask which operator indicates we are finding a row in a table directly using a RID value, and which indicates we are finding a row in a table using a clustered index key, which would you say is which?&amp;nbsp; Take a moment to think about it. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/kalen_delaney/image_60814C43.png"&gt;&lt;img width="84" height="84" title="image" style="margin:0px;border:0px currentColor;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" alt="image" src="http://sqlblog.com/blogs/kalen_delaney/image_thumb_6D7B2C54.png" border="0"&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://sqlblog.com/blogs/kalen_delaney/image_45D4B02A.png"&gt;&lt;img width="92" height="86" title="image" style="margin:0px;border:0px currentColor;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" alt="image" src="http://sqlblog.com/blogs/kalen_delaney/image_thumb_4C1B86B8.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I don’t know about you, but when I just try to figure out these two icons, I think the one on the left looks like it should be the KEY Lookup, and the one on the right should be the RID Lookup. &lt;/p&gt;  &lt;p&gt;But if you check &lt;a href="http://msdn.microsoft.com/en-us/library/ms191158.aspx"&gt;the page in Books Online&lt;/a&gt;, or if you check your own query plans, you see that they are backwards!&lt;/p&gt;  &lt;p&gt;Here is a plan showing a RID Lookup:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/kalen_delaney/image_0459FDD1.png"&gt;&lt;img width="244" height="112" title="image" style="margin:0px;border:0px currentColor;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" alt="image" src="http://sqlblog.com/blogs/kalen_delaney/image_thumb_155E2BB4.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;And here is a plan showing a KEY Lookup:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/kalen_delaney/image_69AD61B7.png"&gt;&lt;img width="244" height="116" title="image" style="margin:0px;border:0px currentColor;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" alt="image" src="http://sqlblog.com/blogs/kalen_delaney/image_thumb_6F880550.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;        &lt;p&gt;Fortunately, the graphical query plan tells you what kind of operation it’s performing, so you can just ignore the picture and read the words. But what’s the point of a graphical plan in that case?&lt;/p&gt;  &lt;p&gt;So are they really backwards? Did someone just make a mistake and link in the wrong file when compiling the SQL Server graphical query plan code? Or am I misinterpreting this? &lt;/p&gt;  &lt;p&gt;I still think graphical query plans are one of the best thing ever added to product, so I’m really not complaining, but I’m just sayin….&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;Have fun, and Happy T-SQL Tuesday!&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff00ff" size="4"&gt;~Kalen&lt;/font&gt;&lt;/p&gt;</description></item><item><title>T-SQL Tuesday #43 – Hello, Operator?</title><link>http://www2.sqlblog.com/blogs/rob_farley/archive/2013/06/02/t-sql-tuesday-43-hello-operator.aspx</link><pubDate>Sun, 02 Jun 2013 11:48:50 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:49316</guid><dc:creator>rob_farley</dc:creator><description>&lt;p&gt;June 11th is next week. It’s a Tuesday, the second Tuesday of the month, making it T-SQL Tuesday! This is your opportunity to write on a specific topic, along with countless* people from around the SQL community (&lt;em&gt;* at least until the end of the day, when it will be quite easy to count how many people joined in&lt;/em&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_1B3B2D1E.jpg" width="150" height="150" /&gt; This month marks 3.5 years since it started, with 42 events held so far.&lt;/p&gt;  &lt;p&gt;This month, for number 43, I’m the host. That means that I set the topic, and this blog post is the one that you need to get a comment into so that I can find your post before I collate them.&lt;/p&gt;  &lt;p&gt;The topic is &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms191158.aspx" target="_blank"&gt;Plan Operators&lt;/a&gt;&lt;/strong&gt;. If you ever write T-SQL, you will almost certainly have looked at execution plans (if you haven’t, go look at some now. I mean really – you should be looking at this stuff). As you look at these things, you will almost certainly have had your interest piqued by some, and tried to figure out a bit more about what’s going on.&lt;/p&gt;  &lt;p&gt;That’s what I want you to write about! One (or more) plan operators that you looked into. It could be a particular aspect of a plan operator, or you could do a deep dive and tell us everything you know. You could relate a tuning story if you want, or it could be completely academic. Don’t just quote Books Online at me, explain what the operator means to you. You could explore the &lt;a href="http://msdn.microsoft.com/en-us/library/ms178082(v=sql.105).aspx" target="_blank"&gt;Compute Scalar&lt;/a&gt; operator, or the many-to-many feature of a &lt;a href="http://msdn.microsoft.com/en-us/library/ms189961(v=sql.105).aspx" target="_blank"&gt;Merge Join&lt;/a&gt;. The &lt;a href="http://msdn.microsoft.com/en-us/library/ms187041(v=sql.105).aspx" target="_blank"&gt;Sequence Project&lt;/a&gt;, or the &lt;a href="http://msdn.microsoft.com/en-us/library/ms191221(v=sql.105).aspx" target="_blank"&gt;Lazy Spool&lt;/a&gt;. You’re bound to have researched one of them at some point (if you never have, take the opportunity this week), and have some wisdom to impart. This is a chance to raise the collective understanding about execution plans!&lt;/p&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="ComputeScalar" border="0" alt="ComputeScalar" src="http://sqlblog.com/blogs/rob_farley/ComputeScalar_1FD137D8.gif" width="52" height="52" /&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="MergeJoin" border="0" alt="MergeJoin" src="http://sqlblog.com/blogs/rob_farley/MergeJoin_6575C1F6.gif" width="52" height="52" /&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="SequenceProject" border="0" alt="SequenceProject" src="http://sqlblog.com/blogs/rob_farley/SequenceProject_6F5AB361.gif" width="52" height="52" /&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="LazySpool" border="0" alt="LazySpool" src="http://sqlblog.com/blogs/rob_farley/LazySpool_34FF3D80.gif" width="52" height="52" /&gt;&lt;/p&gt;  &lt;p&gt;So, the T-SQL Tuesday thing...&lt;/p&gt;  &lt;p&gt;If you haven’t heard about T-SQL Tuesday before, then do this exercise with me. Do a quick search for “T-SQL Tuesday”. If you glance down the results,&amp;#160; you’ll see a bunch of posts either inviting people to a T-SQL Tuesday, contributing in one (the ones that contribute link back to the host), or summarising the posts. The ‘host post’ (which this month is this one!) will have a bunch of comments and trackbacks, pointing to all the contributing posts (and hopefully to the summary too). All-in-all, it makes a terrific resource about that particular subject.&lt;/p&gt;  &lt;p&gt;So here’s what you do!&lt;/p&gt;  &lt;p&gt;1. Some time next Tuesday (GMT) – that’s June 11th 2013 – publish your blog post. If you’re in Australia like me, GMT Tuesday runs from mid-morning on the Tuesday through to mid-morning on Wednesday. If you’re in the US, then it’ll run from Monday evening through to Tuesday evening.&lt;/p&gt;  &lt;p align="left"&gt;2. Make sure that your post includes, somewhere near the top, the T-SQL Tuesday image (from above), with a link to this post. This helps people find the other posts on the topic, and hopefully encourages others to jump in with their own posts. If it helps, just switch to source/HTML mode, and put the following snippet in there:    &lt;br /&gt;&amp;lt;a href=&amp;quot;http://sqlblog.com/blogs/rob_farley/archive/2013/06/02/t-sql-tuesday-43-hello-operator.aspx&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img alt=&amp;quot;TSQL Tuesday&amp;quot; align=&amp;quot;right&amp;quot; border=&amp;quot;0&amp;quot; src=&amp;quot;http://sqlblog.com/blogs/rob_farley/TSQL2sDay150x150_1B3B2D1E.jpg&amp;quot;/&amp;gt;&amp;lt;/a&amp;gt;&lt;/p&gt;  &lt;p&gt;3. Come back to this post, and write a comment, providing a link to your post. That’s probably the only way I’ll know it’s there. You can tweet, sure (use the hashtag #tsql2sday), but I still might not find it.&lt;/p&gt;  &lt;p&gt;4 (optional, but maybe worthwhile). Keep your eye out for other people’s posts, and for when I publish the summary...&lt;/p&gt;  &lt;p&gt;That’s about it – happy writing!&lt;/p&gt;  &lt;p&gt;Remember: 1: Jun 11 &lt;strong&gt;GMT&lt;/strong&gt;; 2: Image with a link; 3: Comment below. &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>Part of the journey: failure</title><link>http://www2.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://www2.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://www2.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://www2.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://www2.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://www2.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://www2.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></channel></rss>