<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblogcasts.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">SQL and the like</title><subtitle type="html" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/atom.aspx</id><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/default.aspx" /><link rel="self" type="application/atom+xml" href="http://sqlblogcasts.com/blogs/sqlandthelike/atom.aspx" /><generator uri="http://communityserver.org" version="3.1.20917.1142">Community Server</generator><updated>2009-08-27T08:22:02Z</updated><entry><title>Output = MAXDOP 1</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/03/04/output-maxdop-1.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/03/04/output-maxdop-1.aspx</id><published>2010-03-04T09:32:00Z</published><updated>2010-03-04T09:32:00Z</updated><content type="html">&lt;p&gt;It is widely know that data modifications on table variables do not support parallelism, Peter Larsson has a good example of that &lt;a href="http://sqlblog.com/blogs/peter_larsson/archive/2009/10/15/performance-consideration-when-using-a-table-variable.aspx" target="_blank"&gt;here&lt;/a&gt; .&amp;nbsp; Whilst tracking down a performance issue,&amp;nbsp; I saw that using the OUTPUT clause also causes parallelism to not be used.&lt;/p&gt;  &lt;p&gt;By way of example,&amp;nbsp; first lets create two tables with a simple parent and child (one to one) relationship, and then populate them with 100,000 rows.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Drop table &lt;/span&gt;Parent&lt;br /&gt;&lt;span style="color:blue;"&gt;Drop table &lt;/span&gt;Child&lt;br /&gt;&lt;span style="color:blue;"&gt;go&lt;br /&gt;create table &lt;/span&gt;Parent&lt;br /&gt;&lt;span style="color:gray;"&gt;(&lt;br /&gt;&lt;/span&gt;id &lt;span style="color:blue;"&gt;integer identity Primary Key&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;br /&gt;&lt;/span&gt;data1 &lt;span style="color:blue;"&gt;char&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;255&lt;span style="color:gray;"&gt;)&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;Create Table &lt;/span&gt;Child&lt;br /&gt;&lt;span style="color:gray;"&gt;(&lt;br /&gt;&lt;/span&gt;id &lt;span style="color:blue;"&gt;integer Primary Key&lt;br /&gt;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;go&lt;br /&gt;insert into &lt;/span&gt;Parent&lt;span style="color:gray;"&gt;(&lt;/span&gt;data1&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;Select top &lt;/span&gt;1000000 &lt;span style="color:gray;"&gt;NULL&lt;br /&gt;  &lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;columns &lt;/span&gt;a &lt;span style="color:gray;"&gt;cross join &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;columns &lt;/span&gt;b&lt;br /&gt;  &lt;br /&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;Child&lt;br /&gt;&lt;span style="color:blue;"&gt;Select &lt;/span&gt;id &lt;span style="color:blue;"&gt;from &lt;/span&gt;Parent&lt;br /&gt;&lt;span style="color:blue;"&gt;go&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;If we then execute &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;update &lt;/span&gt;Parent &lt;br /&gt;&lt;span style="color:blue;"&gt;set    &lt;/span&gt;data1 &lt;span style="color:gray;"&gt;=&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;&amp;#39;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;from   &lt;/span&gt;Parent&lt;br /&gt;&lt;span style="color:gray;"&gt;join   &lt;/span&gt;Child  &lt;span style="color:blue;"&gt;on &lt;/span&gt;Parent&lt;span style="color:gray;"&gt;.&lt;/span&gt;Id &lt;span style="color:gray;"&gt;= &lt;/span&gt;Child&lt;span style="color:gray;"&gt;.&lt;/span&gt;Id&lt;br /&gt;                &lt;span style="color:blue;"&gt;where &lt;/span&gt;Parent&lt;span style="color:gray;"&gt;.&lt;/span&gt;Id &lt;span style="color:gray;"&gt;%&lt;/span&gt;100 &lt;span style="color:gray;"&gt;=&lt;/span&gt;1&lt;br /&gt;                  &lt;span style="color:gray;"&gt;and &lt;/span&gt;Child&lt;span style="color:gray;"&gt;.&lt;/span&gt;id &lt;span style="color:gray;"&gt;%&lt;/span&gt;100 &lt;span style="color:gray;"&gt;=&lt;/span&gt;1&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;We should see an execution plan using parallelism such as&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/Parrelel1_562749BB.jpg"&gt;&lt;img src="http://sqlblogcasts.com/blogs/sqlandthelike/Parrelel1_thumb_75D62383.jpg" style="border:0px none;display:inline;" title="Parrelel1" alt="Parrelel1" width="494" border="0" height="163" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;However,&amp;nbsp; if the OUTPUT clause is now used&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;update &lt;/span&gt;Parent &lt;br /&gt;&lt;span style="color:blue;"&gt;set    &lt;/span&gt;data1 &lt;span style="color:gray;"&gt;=&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;&amp;#39;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;output &lt;/span&gt;inserted&lt;span style="color:gray;"&gt;.&lt;/span&gt;id&lt;br /&gt;&lt;span style="color:blue;"&gt;from   &lt;/span&gt;Parent&lt;br /&gt;&lt;span style="color:gray;"&gt;join   &lt;/span&gt;Child  &lt;span style="color:blue;"&gt;on &lt;/span&gt;Parent&lt;span style="color:gray;"&gt;.&lt;/span&gt;Id &lt;span style="color:gray;"&gt;= &lt;/span&gt;Child&lt;span style="color:gray;"&gt;.&lt;/span&gt;Id&lt;br /&gt;                &lt;span style="color:blue;"&gt;where &lt;/span&gt;Parent&lt;span style="color:gray;"&gt;.&lt;/span&gt;Id &lt;span style="color:gray;"&gt;%&lt;/span&gt;100 &lt;span style="color:gray;"&gt;=&lt;/span&gt;1&lt;br /&gt;                  &lt;span style="color:gray;"&gt;and &lt;/span&gt;Child&lt;span style="color:gray;"&gt;.&lt;/span&gt;id &lt;span style="color:gray;"&gt;%&lt;/span&gt;100 &lt;span style="color:gray;"&gt;=&lt;/span&gt;1&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The execution plan shows that Parallelism was not used&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/Parrelel2_20AE8796.jpg"&gt;&lt;img src="http://sqlblogcasts.com/blogs/sqlandthelike/Parrelel2_thumb_00937AD9.jpg" style="border:0px none;display:inline;" title="Parrelel2" alt="Parrelel2" width="401" border="0" height="178" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Make of that what you will, but i thought that this was a pretty unexpected outcome.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Update : Laurence Hoff has mailed me to note that when the OUTPUT results are captured to a temporary table using the INTO clause,&amp;nbsp; then parallelism is used.&amp;nbsp; Naturally if you use a table variable then there is still no parallelism &amp;nbsp; &lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=13202" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>Cleaning up sys.dm_exec_cached_plans</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/01/27/cleaning-up-sys-dm-exec-cached-plans.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/01/27/cleaning-up-sys-dm-exec-cached-plans.aspx</id><published>2010-01-27T15:33:48Z</published><updated>2010-01-27T15:33:48Z</updated><content type="html">&lt;p&gt;Following on from my previous &lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/01/22/microsoft-follow-best-practices.aspx" target="_blank"&gt;post&lt;/a&gt; in which I noticed that SQLServer itself was artificially bloating sys.dm_exec_cached_plans, the next obvious question is “How can i clear this rubbish out ?”.&amp;#160; On 2008 its simple enough, Microsoft have kindly enhanced &lt;font face="Courier New"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms174283.aspx" target="_blank"&gt;DBCC FREEPROCCACHE&lt;/a&gt;&amp;#160;&lt;/font&gt;&lt;font face="Trebuchet MS"&gt;to accept a plan_handle.&amp;#160; On 2005 things are a bit more tricky.&amp;#160; You could use DBCC FREEPROCCACHE , but that would clear everything out, certainly not a good thing to be happening in a live environment.&amp;#160; It has been blogged about before that &lt;a href="http://msdn.microsoft.com/en-us/library/ms179880.aspx" target="_blank"&gt;sp_create_plan_guide&lt;/a&gt; can be used to purge a specific statement.&amp;#160; That works fine on single statement batches , but multi-statement&amp;#160; batches are not supported as easily.&amp;#160; The solution is in multi-statement batches to create a separate plan for each statement.&amp;#160; Here’s my rough-and-ready routine to clear down sys.dm_exec_cached_plans for msdb statements.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Trebuchet MS"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;declare &lt;/span&gt;@Text &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;max&lt;/span&gt;&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;span style="color:blue;"&gt;Declare &lt;/span&gt;@Plan_handle &lt;span style="color:blue;"&gt;varbinary&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;64&lt;span style="color:gray;"&gt;)

&lt;/span&gt;&lt;span style="color:blue;"&gt;declare &lt;/span&gt;purgecur &lt;span style="color:blue;"&gt;cursor for
 SELECT text&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;plan_handle
   &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;dm_exec_cached_plans 
  &lt;/span&gt;&lt;span style="color:gray;"&gt;CROSS APPLY &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;dm_exec_sql_text&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;plan_handle&lt;span style="color:gray;"&gt;) 
&lt;/span&gt;&lt;span style="color:blue;"&gt;where &lt;/span&gt;Objtype &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Adhoc&amp;#39;
   &lt;/span&gt;&lt;span style="color:gray;"&gt;and &lt;/span&gt;&lt;span style="color:blue;"&gt;text &lt;/span&gt;&lt;span style="color:gray;"&gt;like &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;%msdb.%&amp;#39;
&lt;/span&gt;&lt;span style="color:green;"&gt;--   and plan_handle = 0x06000400E3854A1E40030F8E010000000000000000000000
&lt;/span&gt;&lt;span style="color:blue;"&gt;open &lt;/span&gt;purgeCur
&lt;span style="color:blue;"&gt;while&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;0&lt;span style="color:gray;"&gt;=&lt;/span&gt;0&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;begin 
   Fetch Next from &lt;/span&gt;PurgeCur &lt;span style="color:blue;"&gt;into &lt;/span&gt;@Text&lt;span style="color:gray;"&gt;,&lt;/span&gt;@plan_handle
   
   &lt;span style="color:blue;"&gt;if&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;@@Fetch_Status &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;&amp;gt; &lt;/span&gt;0&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;break

   declare &lt;/span&gt;@CurCount &lt;span style="color:blue;"&gt;integer
   Select &lt;/span&gt;@CurCount &lt;span style="color:gray;"&gt;=&lt;/span&gt;0
   &lt;span style="color:blue;"&gt;declare &lt;/span&gt;@StmtText &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;max&lt;/span&gt;&lt;span style="color:gray;"&gt;)
   &lt;/span&gt;&lt;span style="color:blue;"&gt;declare &lt;/span&gt;purgestmt &lt;span style="color:blue;"&gt;cursor
       for SELECT &lt;/span&gt;&lt;span style="color:magenta;"&gt;substring&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;text&lt;/span&gt;&lt;span style="color:gray;"&gt;,(&lt;/span&gt;qs&lt;span style="color:gray;"&gt;.&lt;/span&gt;statement_start_offset&lt;span style="color:gray;"&gt;+&lt;/span&gt;2&lt;span style="color:gray;"&gt;)/&lt;/span&gt;2&lt;span style="color:gray;"&gt;,
                  (((&lt;/span&gt;&lt;span style="color:blue;"&gt;case when &lt;/span&gt;statement_end_offset&lt;span style="color:gray;"&gt;=-&lt;/span&gt;1 &lt;span style="color:blue;"&gt;then &lt;/span&gt;999998 &lt;span style="color:blue;"&gt;else &lt;/span&gt;statement_end_offset &lt;span style="color:blue;"&gt;end&lt;/span&gt;&lt;span style="color:gray;"&gt;)-&lt;/span&gt;statement_start_offset&lt;span style="color:gray;"&gt;)+&lt;/span&gt;2&lt;span style="color:gray;"&gt;)/&lt;/span&gt;2&lt;span style="color:gray;"&gt;)
             &lt;/span&gt;&lt;span style="color:blue;"&gt;FROM &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;dm_exec_query_stats &lt;/span&gt;&lt;span style="color:blue;"&gt;AS &lt;/span&gt;qs
                  &lt;span style="color:gray;"&gt;CROSS APPLY &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;dm_exec_sql_text&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;sql_handle&lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;AS &lt;/span&gt;st
            &lt;span style="color:blue;"&gt;where &lt;/span&gt;qs&lt;span style="color:gray;"&gt;.&lt;/span&gt;plan_handle &lt;span style="color:gray;"&gt;= &lt;/span&gt;@Plan_handle
   &lt;span style="color:blue;"&gt;open &lt;/span&gt;purgestmt
   
   &lt;span style="color:blue;"&gt;while&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;0&lt;span style="color:gray;"&gt;=&lt;/span&gt;0&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;begin 
       fetch next from &lt;/span&gt;purgestmt &lt;span style="color:blue;"&gt;into &lt;/span&gt;@StmtText
       
       &lt;span style="color:blue;"&gt;if&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;@@Fetch_status&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;&amp;gt;&lt;/span&gt;0&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;break
       select &lt;/span&gt;@CurCount &lt;span style="color:gray;"&gt;=&lt;/span&gt;@Curcount&lt;span style="color:gray;"&gt;+&lt;/span&gt;1
       &lt;span style="color:blue;"&gt;begin try
       exec &lt;/span&gt;&lt;span style="color:maroon;"&gt;sp_create_plan_guide 
                   &lt;/span&gt;@name &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;PlanGuidePurge&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
                   &lt;/span&gt;@stmt &lt;span style="color:gray;"&gt;= &lt;/span&gt;@StmtText&lt;span style="color:gray;"&gt;,
                   &lt;/span&gt;@type &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;SQL&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
                   &lt;/span&gt;@module_or_batch &lt;span style="color:gray;"&gt;= &lt;/span&gt;@Text&lt;span style="color:gray;"&gt;, 
                   &lt;/span&gt;@params &lt;span style="color:gray;"&gt;= NULL, 
                   &lt;/span&gt;@hints &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;OPTION (MaxDop 1)&amp;#39; 
       &lt;/span&gt;&lt;span style="color:blue;"&gt;end try
       begin catch
       end catch           
       if &lt;/span&gt;&lt;span style="color:gray;"&gt;exists(&lt;/span&gt;&lt;span style="color:blue;"&gt;Select &lt;/span&gt;&lt;span style="color:gray;"&gt;* &lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;plan_guides &lt;/span&gt;&lt;span style="color:blue;"&gt;where &lt;/span&gt;name &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;PlanGuidePurge&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;begin    
          exec &lt;/span&gt;&lt;span style="color:maroon;"&gt;sp_control_plan_guide &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;DROP&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;PlanGuidePurge&amp;#39;
       &lt;/span&gt;&lt;span style="color:blue;"&gt;end
   end
   close &lt;/span&gt;purgestmt
   &lt;span style="color:blue;"&gt;deallocate &lt;/span&gt;purgestmt
   &lt;span style="color:blue;"&gt;if&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;@CurCount &lt;span style="color:gray;"&gt;=&lt;/span&gt;0&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;begin 
       begin try
       exec &lt;/span&gt;&lt;span style="color:maroon;"&gt;sp_create_plan_guide 
                   &lt;/span&gt;@name &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;PlanGuidePurge&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
                   &lt;/span&gt;@stmt &lt;span style="color:gray;"&gt;= &lt;/span&gt;@Text&lt;span style="color:gray;"&gt;,
                   &lt;/span&gt;@type &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;SQL&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;, 
                   &lt;/span&gt;@module_or_batch &lt;span style="color:gray;"&gt;= &lt;/span&gt;@Text&lt;span style="color:gray;"&gt;, 
                   &lt;/span&gt;@params &lt;span style="color:gray;"&gt;= NULL, 
                   &lt;/span&gt;@hints &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;OPTION (MaxDop 1)&amp;#39; 
       &lt;/span&gt;&lt;span style="color:blue;"&gt;end try
       begin catch
       end catch           
       if &lt;/span&gt;&lt;span style="color:gray;"&gt;exists(&lt;/span&gt;&lt;span style="color:blue;"&gt;Select &lt;/span&gt;&lt;span style="color:gray;"&gt;* &lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;plan_guides &lt;/span&gt;&lt;span style="color:blue;"&gt;where &lt;/span&gt;name &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;PlanGuidePurge&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;begin    
          exec &lt;/span&gt;&lt;span style="color:maroon;"&gt;sp_control_plan_guide &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;DROP&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:red;"&gt;N&amp;#39;PlanGuidePurge&amp;#39;
       &lt;/span&gt;&lt;span style="color:blue;"&gt;end
    end
   
end
Close &lt;/span&gt;PurgeCur
&lt;span style="color:blue;"&gt;Deallocate &lt;/span&gt;PurgeCur&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;font face="Trebuchet MS"&gt;&lt;font color="#800000" size="1"&gt;&lt;font color="#800000" size="1"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12929" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>Microsoft – Follow best practices – Part 2</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/01/25/microsoft-follow-best-practices-part-2.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/01/25/microsoft-follow-best-practices-part-2.aspx</id><published>2010-01-25T09:03:13Z</published><updated>2010-01-25T09:03:13Z</updated><content type="html">&lt;p&gt;In addition to my previous &lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/01/22/microsoft-follow-best-practices.aspx" target="_blank"&gt;post&lt;/a&gt;, another &lt;a href="http://sqlblogcasts.com/blogs/tonyrogerson/archive/2006/11/10/1280.aspx" target="_blank"&gt;best practice&lt;/a&gt; is to not use NOLOCK and READ UNCOMMITTED transaction isolation level.&lt;/p&gt;  &lt;p&gt;Here’s an excerpt from a profiler trace&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;BEGIN TRAN &lt;/span&gt;UpdateMediaTables

&lt;span style="color:blue;"&gt;SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

DECLARE &lt;/span&gt;@BackupSetId &lt;span style="color:blue;"&gt;int&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;@MediaSetId &lt;span style="color:blue;"&gt;int&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;@LogDevName &lt;span style="color:blue;"&gt;varchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;512&lt;span style="color:gray;"&gt;)

&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;@MediaSetId &lt;span style="color:gray;"&gt;= &lt;/span&gt;media_set_id
&lt;span style="color:blue;"&gt;FROM &lt;/span&gt;msdb&lt;span style="color:gray;"&gt;..&lt;/span&gt;backupmediafamily &lt;span style="color:blue;"&gt;AS &lt;/span&gt;bmf &lt;span style="color:blue;"&gt;WITH &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;NOLOCK&lt;/span&gt;&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;span style="color:blue;"&gt;WHERE &lt;/span&gt;&lt;span style="color:magenta;"&gt;substring&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;bmf&lt;span style="color:gray;"&gt;.&lt;/span&gt;physical_device_name&lt;span style="color:gray;"&gt;,&lt;/span&gt;5&lt;span style="color:gray;"&gt;,&lt;/span&gt;36&lt;span style="color:gray;"&gt;) = &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;80A2E6DE-3E95-4645-B476-09E37306FF8C&amp;#39;

&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;@BackupSetId &lt;span style="color:gray;"&gt;= &lt;/span&gt;backup_set_id
&lt;span style="color:blue;"&gt;FROM &lt;/span&gt;msdb&lt;span style="color:gray;"&gt;..&lt;/span&gt;backupset &lt;span style="color:blue;"&gt;WITH &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;NOLOCK&lt;/span&gt;&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;span style="color:blue;"&gt;WHERE &lt;/span&gt;media_set_id &lt;span style="color:gray;"&gt;= &lt;/span&gt;@MediaSetId&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;So, not only do we have no consistency, but also a non–SARGable lookup.&lt;/p&gt;

&lt;p&gt;I’ve updated my previous &lt;a href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=526485" target="_blank"&gt;connect item&lt;/a&gt; to reflect this also. &lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12915" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>Microsoft – Follow best practices!</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/01/22/microsoft-follow-best-practices.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/01/22/microsoft-follow-best-practices.aspx</id><published>2010-01-22T10:30:07Z</published><updated>2010-01-22T10:30:07Z</updated><content type="html">&lt;p&gt;Best practice is to use parametrized queries to enable plan reuse.&amp;#160; Will someone please tell Microsoft this.&amp;#160; &lt;/p&gt;  &lt;p&gt;Presently dm_exec_cached_plans on our live server has been bloated by 550mb of adhoc queries by SqlAgent (possibly a few other services)&lt;/p&gt;  &lt;p&gt;Here’s how im calculating the total bloat value&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;&lt;span style="color:magenta;"&gt;sum&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;size_in_bytes&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;span style="color:blue;"&gt;FROM &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;dm_exec_cached_plans 
&lt;/span&gt;&lt;span style="color:gray;"&gt;CROSS APPLY &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;dm_exec_sql_text&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;plan_handle&lt;span style="color:gray;"&gt;) 
&lt;/span&gt;&lt;span style="color:blue;"&gt;where &lt;/span&gt;Objtype &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Adhoc&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;
  and &lt;/span&gt;&lt;span style="color:blue;"&gt;text &lt;/span&gt;&lt;span style="color:gray;"&gt;like &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;%msdb.%&amp;#39;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Which can be broken down to a query by query basis of&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;&lt;span style="color:magenta;"&gt;sum&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;size_in_bytes&lt;span style="color:gray;"&gt;),&lt;/span&gt;&lt;span style="color:magenta;"&gt;count&lt;/span&gt;&lt;span style="color:gray;"&gt;(*),&lt;/span&gt;&lt;span style="color:magenta;"&gt;substring&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;text&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;1&lt;span style="color:gray;"&gt;,&lt;/span&gt;100&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;span style="color:blue;"&gt;FROM &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;dm_exec_cached_plans 
&lt;/span&gt;&lt;span style="color:gray;"&gt;CROSS APPLY &lt;/span&gt;&lt;span style="color:green;"&gt;sys&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;dm_exec_sql_text&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;plan_handle&lt;span style="color:gray;"&gt;) 
&lt;/span&gt;&lt;span style="color:blue;"&gt;where &lt;/span&gt;&lt;span style="color:gray;"&gt;&lt;font color="#000000"&gt;Objtype &lt;/font&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Adhoc&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="color:gray;"&gt;  and &lt;/span&gt;&lt;span style="color:blue;"&gt;text &lt;/span&gt;&lt;span style="color:gray;"&gt;like &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;%msdb.%&amp;#39;
&lt;/span&gt;&lt;span style="color:blue;"&gt;group by &lt;/span&gt;&lt;span style="color:magenta;"&gt;substring&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;text&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;1&lt;span style="color:gray;"&gt;,&lt;/span&gt;100&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;order by &lt;/span&gt;1 &lt;span style="color:blue;"&gt;desc
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connect item &lt;a href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=526485" target="_blank"&gt;here&lt;/a&gt; if you feel like voting.&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12898" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>Age calculation with SQL Server</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/12/08/age-calculation-with-sql-server.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/12/08/age-calculation-with-sql-server.aspx</id><published>2009-12-08T09:43:00Z</published><updated>2009-12-08T09:43:00Z</updated><content type="html">&lt;p&gt;There seem to be many different methods being suggested to calculate an age in SQLServer.&amp;nbsp; Some are quite complex but most are simply wrong.&amp;nbsp; This is by far the simplest and accurate method that I know.&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Declare &lt;/span&gt;@Date1 &lt;span style="color:blue;"&gt;datetime&lt;br /&gt;Declare &lt;/span&gt;@Date2 &lt;span style="color:blue;"&gt;datetime&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Select &lt;/span&gt;@Date1 &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;15Feb1971&amp;#39;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;Select &lt;/span&gt;@Date2 &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;08Dec2009&amp;#39;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;select CASE&lt;br /&gt;WHEN &lt;/span&gt;&lt;span style="color:magenta;"&gt;dateadd&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;year&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:magenta;"&gt;datediff &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;year&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;@Date1&lt;span style="color:gray;"&gt;, &lt;/span&gt;@Date2&lt;span style="color:gray;"&gt;), &lt;/span&gt;@Date1&lt;span style="color:gray;"&gt;) &amp;gt; &lt;/span&gt;@Date2&lt;br /&gt;&lt;span style="color:blue;"&gt;THEN &lt;/span&gt;&lt;span style="color:magenta;"&gt;datediff &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;year&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;@Date1&lt;span style="color:gray;"&gt;, &lt;/span&gt;@Date2&lt;span style="color:gray;"&gt;) - &lt;/span&gt;1&lt;br /&gt;&lt;span style="color:blue;"&gt;ELSE &lt;/span&gt;&lt;span style="color:magenta;"&gt;datediff &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;year&lt;/span&gt;&lt;span style="color:gray;"&gt;, &lt;/span&gt;@Date1&lt;span style="color:gray;"&gt;, &lt;/span&gt;@Date2&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;END as &lt;/span&gt;Age&lt;/pre&gt;

&lt;p&gt;This even copes with the tricky situation of 29th feb,&amp;nbsp; although I cant say correctly as according to &lt;a href="http://en.wikipedia.org/wiki/February_29" target="_blank"&gt;Wikipedia&lt;/a&gt; birthdays may be on the 28th of Feb or 1st March.&lt;/p&gt;

&lt;p&gt;This post has been part of T-SQL Tuesday, hosted this month by &lt;a href="http://sqlblog.com/blogs/adam_machanic/archive/2009/11/30/invitation-to-participate-in-t-sql-tuesday-001-date-time-tricks.aspx" target="_blank"&gt;&lt;font color="#0066cc"&gt;Adam Machanic&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12691" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>Phil Factor Speed Phreak SQL Challenge Number 3</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/12/04/phil-factor-challenge-number-3.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/12/04/phil-factor-challenge-number-3.aspx</id><published>2009-12-04T11:06:00Z</published><updated>2009-12-04T11:06:00Z</updated><content type="html">&lt;p&gt;The latest Phil Factor challenge is now active &lt;a href="http://ask.sqlservercentral.com/questions/2295/phil-factor-speed-phreak-challenge-3" title="here"&gt;here&lt;/a&gt;. The prize has now been increased to $100 &lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12678" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author><category term="Optimizer" scheme="http://sqlblogcasts.com/blogs/sqlandthelike/archive/tags/Optimizer/default.aspx" /><category term="Challenge" scheme="http://sqlblogcasts.com/blogs/sqlandthelike/archive/tags/Challenge/default.aspx" /><category term="SpeedPhreak" scheme="http://sqlblogcasts.com/blogs/sqlandthelike/archive/tags/SpeedPhreak/default.aspx" /></entry><entry><title>My first useful powershell script – capturing performance counters</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/11/30/my-first-useful-powershell-script-capturing-performance-counters.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/11/30/my-first-useful-powershell-script-capturing-performance-counters.aspx</id><published>2009-11-30T10:52:00Z</published><updated>2009-11-30T10:52:00Z</updated><content type="html">&lt;p&gt;&lt;span style="color:blue;"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;After playing around with powershell a bit, I managed to do something quite useful.&amp;nbsp; There are a multitude of ways to capture performance counters but I think this will have the advantage of being able to be fired by SqlAgent (or another timer process) every X many seconds.&amp;nbsp; All you now need to do is process the data within Excel (or power pivot as shown by David Castro&amp;nbsp; &lt;a href="http://sqlblogcasts.com/blogs/reborndba/archive/2009/11/26/using-powerpivot-to-read-my-perfmon-data.aspx" target="_blank"&gt;here&lt;/a&gt; ).&amp;nbsp; For every server in servers.txt it will collect the counters in counters.txt&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;$Servers &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:blue;"&gt;get&lt;/span&gt;&lt;span style="color:gray;"&gt;-&lt;/span&gt;content &lt;span style="color:blue;"&gt;c:&lt;/span&gt;\&lt;span style="color:green;"&gt;&lt;font color="#000000"&gt;servers&lt;/font&gt;&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;txt&lt;br /&gt;&lt;span style="color:blue;"&gt;$CounterList &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:blue;"&gt;Get&lt;/span&gt;&lt;span style="color:gray;"&gt;-&lt;/span&gt;Content &lt;span style="color:blue;"&gt;c:&lt;/span&gt;\counters&lt;span style="color:gray;"&gt;.&lt;/span&gt;txt&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;$sw &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;new&lt;span style="color:gray;"&gt;-&lt;/span&gt;&lt;span style="color:blue;"&gt;object system&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;IO&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;StreamWriter&lt;span style="color:gray;"&gt;(&lt;/span&gt;&amp;quot;c:\perf.res&amp;quot;&lt;span style="color:gray;"&gt;,&lt;/span&gt;1&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;$Counters &lt;/span&gt;&lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:blue;"&gt;$CounterList &lt;/span&gt;&lt;span style="color:gray;"&gt;| &lt;/span&gt;&lt;span style="color:blue;"&gt;Get&lt;/span&gt;&lt;span style="color:gray;"&gt;-&lt;/span&gt;&lt;span style="color:blue;"&gt;Counter &lt;/span&gt;&lt;span style="color:gray;"&gt;-&lt;/span&gt;computer &lt;span style="color:blue;"&gt;$Servers&lt;br /&gt;&lt;/span&gt;foreach&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;$counter &lt;/span&gt;&lt;span style="color:gray;"&gt;in &lt;/span&gt;&lt;span style="color:blue;"&gt;$counters&lt;/span&gt;&lt;span style="color:gray;"&gt;){&lt;br /&gt; &lt;/span&gt;&lt;span style="color:blue;"&gt;$counter&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;ToString&lt;span style="color:gray;"&gt;()&lt;br /&gt; &lt;/span&gt;foreach&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;$sampleset &lt;/span&gt;&lt;span style="color:gray;"&gt;in &lt;/span&gt;&lt;span style="color:blue;"&gt;$counter&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;CounterSamples&lt;span style="color:gray;"&gt;){&lt;br /&gt;       &lt;/span&gt;&lt;span style="color:blue;"&gt;$sw&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;writeline&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;$sampleset&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;Timestamp&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;ToString&lt;span style="color:gray;"&gt;()+&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;+&lt;/span&gt;&lt;span style="color:blue;"&gt;$sampleset&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;Path &lt;/span&gt;&lt;span style="color:gray;"&gt;+ &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;,&amp;#39; &lt;/span&gt;&lt;span style="color:gray;"&gt;+&lt;/span&gt;&lt;span style="color:blue;"&gt;$sampleset&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;CookedValue &lt;span style="color:gray;"&gt;)  &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;$sw&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;close&lt;/span&gt;&lt;span style="color:gray;"&gt;()&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Example Counters.Txt&lt;/p&gt;

&lt;p&gt;&lt;font size="1" face="Courier New"&gt;\Memory\Available MBytes 
    &lt;br /&gt;\Paging File(_total)\% Usage 

    &lt;br /&gt;\PhysicalDisk(_total)\% Disk Time 

    &lt;br /&gt;\PhysicalDisk(_total)\Avg. Disk Bytes/Read 

    &lt;br /&gt;\PhysicalDisk(_total)\Avg. Disk Bytes/Write 

    &lt;br /&gt;\PhysicalDisk(_total)\Disk Reads/Sec 

    &lt;br /&gt;\PhysicalDisk(_total)\Disk Writes/Sec 

    &lt;br /&gt;\SqlServer:Buffer Manager\Buffer cache hit ratio 

    &lt;br /&gt;\SqlServer:Buffer Manager\Page life expectancy 

    &lt;br /&gt;\SqlServer:General Statistics\User Connections 

    &lt;br /&gt;\SqlServer:Memory Manager\Memory Grants Pending 

    &lt;br /&gt;\System\Processor Queue Length 

    &lt;br /&gt;&lt;/font&gt;&lt;font size="1" face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;Example Servers.Txt&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="1" face="Courier New"&gt;Server1 
    &lt;br /&gt;Server2&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Enjoy&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12651" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>The Observer Effect In Action</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/11/24/the-observer-effect-in-action.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/11/24/the-observer-effect-in-action.aspx</id><published>2009-11-24T10:16:05Z</published><updated>2009-11-24T10:16:05Z</updated><content type="html">&lt;p&gt;I’ve put my hand up to to a quick 10 - 15 minute slot at the London user group, so I was getting my scripts together to do a presentation based on my &lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/10/15/udf-overhead-a-simple-example.aspx" target="_blank"&gt;UDF Overhead&lt;/a&gt; blog entry.&amp;#160; Naturally this being my first time talking, I wanted to make sure that I was accurate in terms of the statement timings and how I was interpreting the results.&amp;#160; After running the examples a few times I started to notice a discrepancy that I was wasn&amp;#39;t expecting.&lt;/p&gt;  &lt;p&gt;Executing the UDF with ‘SET STATISTICS TIME ON’ was visibly slower that without. In fact in profiler the duration time with stats time on was 2056ms, without it duration time was 233ms. This was the only difference. Testing on 2008 showed the same effect but to a lesser degree.&lt;/p&gt;  &lt;p&gt;Heres the script im testing with.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Drop Function &lt;/span&gt;GetSalesCommission
&lt;span style="color:blue;"&gt;go
Create Function &lt;/span&gt;GetSalesCommission&lt;span style="color:gray;"&gt;(&lt;/span&gt;@SalesAmount &lt;span style="color:blue;"&gt;money&lt;/span&gt;&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;span style="color:blue;"&gt;returns money
as
begin 
    Declare &lt;/span&gt;@CommissionAmount &lt;span style="color:blue;"&gt;money
    Select &lt;/span&gt;@CommissionAmount &lt;span style="color:gray;"&gt;= (&lt;/span&gt;@SalesAmount&lt;span style="color:gray;"&gt;/&lt;/span&gt;100.0&lt;span style="color:gray;"&gt;) * &lt;/span&gt;5
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;@CommissionAmount
&lt;span style="color:blue;"&gt;end
go&lt;/span&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;SET STATISTICS TIME ON
select &lt;/span&gt;&lt;span style="color:magenta;"&gt;sum&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;GetSalesCommission&lt;span style="color:gray;"&gt;(&lt;/span&gt;SubTotal&lt;span style="color:gray;"&gt;))  &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;Commission
  &lt;span style="color:blue;"&gt;from &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderHeader
&lt;span style="color:blue;"&gt;go
SET STATISTICS TIME OFF
select &lt;/span&gt;&lt;span style="color:magenta;"&gt;sum&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;GetSalesCommission&lt;span style="color:gray;"&gt;(&lt;/span&gt;SubTotal&lt;span style="color:gray;"&gt;))  &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;Commission
  &lt;span style="color:blue;"&gt;from &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderHeader
&lt;span style="color:blue;"&gt;go&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;And a screen shot of the profiler output&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/statstime_04A27B13.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="statstime" border="0" alt="statstime" src="http://sqlblogcasts.com/blogs/sqlandthelike/statstime_thumb_2B709153.jpg" width="506" height="83" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;With this in mind,I’m certainly going to re-asses a few performance evaluation practices.&amp;#160; It doesn&amp;#39;t completely negate my previous post on UDF Overheads but a large portion of the timings would seem to be related to this. &lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12594" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>And the winner is….</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/11/15/and-the-winner-is.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/11/15/and-the-winner-is.aspx</id><published>2009-11-15T10:32:46Z</published><updated>2009-11-15T10:32:46Z</updated><content type="html">&lt;p&gt;Me.&amp;#160; Ok, so there wasn&amp;#39;t a massive field of runners and riders, in the &lt;a href="http://ask.sqlservercentral.com/questions/826/the-fifo-stock-inventory-sql-problem"&gt;second Phil Factor challenge&lt;/a&gt;.&amp;#160; But I&amp;#39;m still feeling pretty chuffed.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/PhilFactorSQLSpeedPhreakAward_71CEDAFE.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:block;float:none;margin-left:auto;border-top:0px;margin-right:auto;border-right:0px;" title="PhilFactorSQLSpeedPhreakAward" border="0" alt="PhilFactorSQLSpeedPhreakAward" src="http://sqlblogcasts.com/blogs/sqlandthelike/PhilFactorSQLSpeedPhreakAward_thumb_252A9E5B.jpg" width="258" height="151" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12526" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>Another T-SQL Challenge</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/10/29/another-t-sql-challenge.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/10/29/another-t-sql-challenge.aspx</id><published>2009-10-29T15:34:00Z</published><updated>2009-10-29T15:34:00Z</updated><content type="html">&lt;p&gt;Phil Factor has posted up another SQL challenge.&amp;nbsp; Its a goodie and a $60 
amazon voucher is up for grabs.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Give it a try &lt;a href="http://ask.sqlservercentral.com/questions/826/the-fifo-stock-inventory-sql-problem" target="_blank"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12466" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>UDF Overhead – A simple example</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/10/15/udf-overhead-a-simple-example.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/10/15/udf-overhead-a-simple-example.aspx</id><published>2009-10-15T08:07:00Z</published><updated>2009-10-15T08:07:00Z</updated><content type="html">&lt;p&gt;When Microsoft first announced that in SQLServer 2000 they were introducing user defined functions,&amp;#160; I thought “Excellent, that will really help my system”.&amp;#160; However,&amp;#160; it soon became apparent that there is a big overhead in calling them.&amp;#160; Here’s a really simple example of how to waste some system resources.&amp;#160; &lt;/p&gt;  &lt;p&gt;Here is a simple udf&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Create function &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;CalcCommission&lt;span style="color:gray;"&gt;(&lt;/span&gt;@Price &lt;span style="color:blue;"&gt;Money&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;returns money&lt;br /&gt;as&lt;br /&gt;begin &lt;br /&gt;  Declare &lt;/span&gt;@Commission &lt;span style="color:blue;"&gt;money&lt;br /&gt;  Select &lt;/span&gt;@Commission &lt;span style="color:gray;"&gt;= (&lt;/span&gt;@Price&lt;span style="color:gray;"&gt;/&lt;/span&gt;100.000&lt;span style="color:gray;"&gt;)*&lt;/span&gt;5&lt;br /&gt;  &lt;span style="color:blue;"&gt;return &lt;/span&gt;@Commission&lt;br /&gt;&lt;span style="color:blue;"&gt;end&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Nothing special there, it just calculates a sale persons commission at a rate of 5%.&amp;#160; So lets apply that to the whole of the SalesOrderDetail table.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;select &lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;,&lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;calcCommission&lt;span style="color:gray;"&gt;(&lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;From &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderDetail&lt;span style="color:gray;"&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Job done,&amp;#160; report written, push the code live and even better you have a function that can be re-used in different pieces of code many times over.&amp;#160; But what cost has that come as ?&amp;#160; Using ‘SET STATISTICS TIME’ is pretty graphic.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;select &lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;,(&lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;/&lt;/span&gt;100.000&lt;span style="color:gray;"&gt;)*&lt;/span&gt;5  &lt;span style="color:blue;"&gt;From &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderDetail&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;SQL Server Execution Times:&lt;br /&gt;  CPU time = 125 ms,  elapsed time = 784 ms.&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;select &lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;,&lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;calcCommission&lt;span style="color:gray;"&gt;(&lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;)  &lt;/span&gt;&lt;span style="color:blue;"&gt;From &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderDetail&lt;span style="color:gray;"&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;SQL Server Execution Times:&lt;br /&gt;  CPU time = 1625 ms,  elapsed time = 1795 ms.&lt;/pre&gt;

&lt;p&gt;Yes, its takes over twice as long using the udf as not,&amp;#160; and just look at the CPU time.&amp;#160; So what are your alternatives ?&amp;#160; An inline function ?&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Create Function &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;InlineCalcCommission&lt;span style="color:gray;"&gt;(&lt;/span&gt;@Price &lt;span style="color:blue;"&gt;Money&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;returns table&lt;br /&gt;as&lt;br /&gt;return select &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;@Price&lt;span style="color:gray;"&gt;/&lt;/span&gt;100.000&lt;span style="color:gray;"&gt;)*&lt;/span&gt;5  &lt;span style="color:blue;"&gt;as &lt;/span&gt;Commission&lt;span style="color:gray;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;select &lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;,&lt;/span&gt;Commission&lt;span style="color:gray;"&gt;.&lt;/span&gt;Commission&lt;br /&gt;  &lt;span style="color:blue;"&gt;From &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderDetail &lt;span style="color:gray;"&gt;cross apply &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;InlineCalcCommission&lt;span style="color:gray;"&gt;(&lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;Commission&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;SQL Server Execution Times:&lt;br /&gt;  CPU time = 156 ms,  elapsed time = 984 ms.&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Which is much better,&amp;#160; or my own personal favourite (call me old fashioned)&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Create View &lt;/span&gt;SalesWithCommission&lt;br /&gt;&lt;span style="color:blue;"&gt;as&lt;br /&gt;select &lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;,(&lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;/&lt;/span&gt;100.000&lt;span style="color:gray;"&gt;)*&lt;/span&gt;5  &lt;span style="color:blue;"&gt;From &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderDetail&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Add this to the fact that the execution costs of functions are hidden in an execution plan,&amp;#160; this is why they are my penultimate port of call.&amp;#160; The last being a cursor.

&lt;p&gt;Update 24Nov2009 : Please see my follow up blog post at &lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/11/24/the-observer-effect-in-action.aspx" target="_blank"&gt;http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/11/24/the-observer-effect-in-action.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12423" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>Returning a chain of events with a recursive CTE</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/09/18/returning-a-chain-of-events-with-a-recursive-cte.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/09/18/returning-a-chain-of-events-with-a-recursive-cte.aspx</id><published>2009-09-18T12:00:00Z</published><updated>2009-09-18T12:00:00Z</updated><content type="html">&lt;table cellpadding="2" cellspacing="0"&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;This is a question that cropped up &lt;a href="http://www.sqlservercentral.com/Forums/Topic789373-8-1.aspx" target="_blank"&gt;SQLServerCentral&lt;/a&gt;.           &lt;br /&gt;Imagine you have a list of dates, for which you need to know the next day after a specified interval.&amp;nbsp; &lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;table cellpadding="2" cellspacing="0"&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;br /&gt;So in this list you want to return those with an interval of 3Days (ie those in &lt;font color="#ff0000"&gt;Red&lt;/font&gt;)          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;table cellpadding="2" cellspacing="0"&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;font color="#ff0000"&gt;01Jan&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;02Jan&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;&lt;font color="#ff0000"&gt;07jan&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;&lt;font color="#ff0000"&gt;11Jan&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;12Jan&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;&lt;font color="#ff0000"&gt;28jan&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;table cellpadding="2" cellspacing="0"&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&amp;nbsp;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;To add further complication there are also multiple ranges.&amp;nbsp; Heres some sample data&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;drop table &lt;/span&gt;#DateSteps&lt;br /&gt;&lt;span style="color:blue;"&gt;go&lt;br /&gt;Create table &lt;/span&gt;#DateSteps&lt;br /&gt;&lt;span style="color:gray;"&gt;(&lt;br /&gt;   &lt;/span&gt;Handler   &lt;span style="color:blue;"&gt;integer&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;br /&gt;   &lt;/span&gt;EventDate &lt;span style="color:blue;"&gt;smalldatetime&lt;br /&gt;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;go&lt;br /&gt;Create unique index &lt;/span&gt;idxDateSteps &lt;span style="color:blue;"&gt;on &lt;/span&gt;#DateSteps&lt;span style="color:gray;"&gt;(&lt;/span&gt;handler&lt;span style="color:gray;"&gt;,&lt;/span&gt;EventDate&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;go&lt;br /&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;1&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;01jan1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;1&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;07jan1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;1&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;11jan1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;1&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;12jan1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;1&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;28jan1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;1&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;08mar1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;2&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;02jan1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;2&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;04jan1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;2&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;10jan1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;2&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;12jan1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;insert into &lt;/span&gt;#dateSteps &lt;span style="color:blue;"&gt;values&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;2&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;15mar1990&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span style="color:gray;"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;table cellpadding="2" cellspacing="0"&gt;
    &lt;tr&gt;
      &lt;td valign="top"&gt;The key to this routine is the use of row_number() within the derived table at the recursive element of the CTE.&amp;nbsp; This enables us to return only the next row that is three days or more after the input date.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;with &lt;/span&gt;cteStartDates&lt;span style="color:gray;"&gt;(&lt;/span&gt;Handler&lt;span style="color:gray;"&gt;,&lt;/span&gt;EventDate&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;as&lt;br /&gt;&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;br /&gt;   &lt;/span&gt;&lt;span style="color:blue;"&gt;Select &lt;/span&gt;Handler&lt;span style="color:gray;"&gt;,&lt;br /&gt;          &lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;EventDate&lt;span style="color:gray;"&gt;)&lt;br /&gt;     &lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;#datesteps&lt;br /&gt;    &lt;span style="color:blue;"&gt;group by &lt;/span&gt;Handler&lt;br /&gt;&lt;span style="color:gray;"&gt;),&lt;br /&gt;&lt;/span&gt;CteRecursiveSkip&lt;span style="color:gray;"&gt;(&lt;/span&gt;Handler&lt;span style="color:gray;"&gt;,&lt;/span&gt;EventDate&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;as&lt;br /&gt;&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;br /&gt;   &lt;/span&gt;&lt;span style="color:blue;"&gt;Select &lt;/span&gt;Handler&lt;span style="color:gray;"&gt;,&lt;/span&gt;EventDate&lt;br /&gt;     &lt;span style="color:blue;"&gt;from &lt;/span&gt;cteStartDates&lt;br /&gt;   &lt;span style="color:blue;"&gt;union &lt;/span&gt;&lt;span style="color:gray;"&gt;all&lt;br /&gt;   &lt;/span&gt;&lt;span style="color:blue;"&gt;Select &lt;/span&gt;x&lt;span style="color:gray;"&gt;.&lt;/span&gt;Handler&lt;span style="color:gray;"&gt;,&lt;/span&gt;x&lt;span style="color:gray;"&gt;.&lt;/span&gt;EventDate&lt;br /&gt;     &lt;span style="color:blue;"&gt;from &lt;/span&gt;&lt;span style="color:gray;"&gt;( &lt;br /&gt;          &lt;/span&gt;&lt;span style="color:blue;"&gt;Select &lt;/span&gt;#datesteps&lt;span style="color:gray;"&gt;.&lt;/span&gt;Handler&lt;span style="color:gray;"&gt;,&lt;/span&gt;#datesteps&lt;span style="color:gray;"&gt;.&lt;/span&gt;EventDate&lt;span style="color:gray;"&gt;,&lt;br /&gt;                 &lt;/span&gt;RowNum &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:magenta;"&gt;row_number&lt;/span&gt;&lt;span style="color:gray;"&gt;() &lt;/span&gt;&lt;span style="color:gray;"&gt;&lt;br /&gt;                 &lt;/span&gt;&lt;span style="color:blue;"&gt;over &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;partition by &lt;/span&gt;#datesteps&lt;span style="color:gray;"&gt;.&lt;/span&gt;Handler &lt;span style="color:gray;"&gt;&lt;br /&gt;                          &lt;/span&gt;&lt;span style="color:blue;"&gt;order by &lt;/span&gt;#datesteps&lt;span style="color:gray;"&gt;.&lt;/span&gt;EventDate&lt;span style="color:gray;"&gt;)&lt;br /&gt;            &lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;CteRecursiveSkip&lt;br /&gt;            &lt;span style="color:gray;"&gt;join &lt;/span&gt;#datesteps &lt;br /&gt;              &lt;span style="color:blue;"&gt;on &lt;/span&gt;#datesteps&lt;span style="color:gray;"&gt;.&lt;/span&gt;Handler &lt;span style="color:gray;"&gt;= &lt;/span&gt;CteRecursiveSkip&lt;span style="color:gray;"&gt;.&lt;/span&gt;Handler&lt;br /&gt;             &lt;span style="color:gray;"&gt;and &lt;/span&gt;#datesteps&lt;span style="color:gray;"&gt;.&lt;/span&gt;Eventdate &lt;span style="color:gray;"&gt;&amp;gt;= &lt;/span&gt;CteRecursiveSkip&lt;span style="color:gray;"&gt;.&lt;/span&gt;EventDate&lt;span style="color:gray;"&gt;+&lt;/span&gt;3&lt;br /&gt;      &lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;x&lt;br /&gt;    &lt;span style="color:blue;"&gt;where &lt;/span&gt;x&lt;span style="color:gray;"&gt;.&lt;/span&gt;RowNum &lt;span style="color:gray;"&gt;= &lt;/span&gt;1&lt;br /&gt;&lt;span style="color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;Select &lt;/span&gt;&lt;span style="color:gray;"&gt;* &lt;br /&gt;  &lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;CteRecursiveSkip&lt;br /&gt; &lt;span style="color:blue;"&gt;order by &lt;/span&gt;Handler&lt;span style="color:gray;"&gt;,&lt;/span&gt;EventDate&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;table cellpadding="2" cellspacing="0"&gt;
    &lt;tr&gt;
      &lt;td valign="top"&gt;Yet another cursor resigned to the garbage can.&amp;nbsp; Performance should also be quite good across large datasets.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12301" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>DateTime Lookups</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/09/11/datetime-lookups.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/09/11/datetime-lookups.aspx</id><published>2009-09-11T07:55:00Z</published><updated>2009-09-11T07:55:00Z</updated><content type="html">&lt;p&gt;Heres a little something that &lt;a href="http://sqlblogcasts.com/blogs/simons/" target="_blank"&gt;Simon Sabin&lt;/a&gt; mentioned at the London PASS user group last night that I wasnt aware of.&lt;/p&gt;  &lt;p&gt;Ive lost count of the amount of queries I have that are some derivative of&amp;nbsp; &amp;gt;= Midnight of a day and &amp;lt; Midnight of day +1. In SQLServer 2008 the engine now does the work for you.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;select &lt;/span&gt;&lt;span style="color:gray;"&gt;*&lt;br /&gt;  &lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderHeader &lt;br /&gt; &lt;span style="color:blue;"&gt;where &lt;/span&gt;&lt;span style="color:magenta;"&gt;CAST&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;OrderDate &lt;span style="color:blue;"&gt;as DATE&lt;/span&gt;&lt;span style="color:gray;"&gt;) =&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;20010701&amp;#39;&lt;br /&gt; &lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span style="color:red;"&gt;&lt;font color="#000000"&gt;No great surprises so far, but internally the engine has transformed it into a BETWEEN query. So, if you add an index &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;create index &lt;/span&gt;idxSalesOrderHeaderDate &lt;br /&gt;    &lt;span style="color:blue;"&gt;on &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderHeader&lt;span style="color:gray;"&gt;(&lt;/span&gt;OrderDate&lt;span style="color:gray;"&gt;) &lt;br /&gt;    &lt;/span&gt;include &lt;span style="color:gray;"&gt;(&lt;/span&gt;SalesOrderId&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;span style="color:red;"&gt;&lt;font color="#000000"&gt;and then look at the query plan …&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="color:red;"&gt;&lt;font color="#000000"&gt;&lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/sohidx_06F69E5B.jpg"&gt;&lt;img src="http://sqlblogcasts.com/blogs/sqlandthelike/sohidx_thumb_4079AE52.jpg" style="border:0px none;display:inline;" title="sohidx" alt="sohidx" width="498" border="0" height="257" /&gt;&lt;/a&gt; &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="color:red;"&gt;&lt;font color="#000000"&gt;Fabulous, an index seek. &lt;/font&gt;&lt;/span&gt;&lt;span style="color:red;"&gt;&lt;font color="#000000"&gt;How simple is that ?&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:red;"&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12271" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author></entry><entry><title>BUG - Use of ranking functions result in an inefficient query plan</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/09/08/bug-use-of-ranking-functions-result-in-an-inefficient-query-plan.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/09/08/bug-use-of-ranking-functions-result-in-an-inefficient-query-plan.aspx</id><published>2009-09-08T07:12:00Z</published><updated>2009-09-08T07:12:00Z</updated><content type="html">&lt;p&gt;In SQL2005 (9.00.4207.00), if you use a ranking function within a view or CTE, then an inefficient query plan can be produced.&lt;/p&gt;  &lt;p&gt;First off in Adventure works create this index &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Create Index &lt;/span&gt;idxLastName &lt;span style="color:blue;"&gt;on &lt;/span&gt;Person&lt;span style="color:gray;"&gt;.&lt;/span&gt;Contact&lt;span style="color:gray;"&gt;(&lt;/span&gt;LastName&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;and then consider these similar queries:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;select &lt;/span&gt;ContactId&lt;span style="color:gray;"&gt;,&lt;br /&gt;       &lt;/span&gt;LastName&lt;span style="color:gray;"&gt;,&lt;br /&gt;     &lt;/span&gt;&lt;span style="color:magenta;"&gt;row_number&lt;/span&gt;&lt;span style="color:gray;"&gt;() &lt;/span&gt;&lt;span style="color:blue;"&gt;over&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;partition by &lt;/span&gt;LastName &lt;span style="color:blue;"&gt;order by &lt;/span&gt;ContactId&lt;span style="color:gray;"&gt;) &lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;[AdventureWorks]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Person]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Contact] &lt;br /&gt;&lt;span style="color:blue;"&gt;where &lt;/span&gt;LastName &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Smith&amp;#39;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;go&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;create view &lt;/span&gt;vwContacts&lt;br /&gt;&lt;span style="color:blue;"&gt;as&lt;br /&gt;select &lt;/span&gt;ContactId&lt;span style="color:gray;"&gt;,&lt;br /&gt;       &lt;/span&gt;LastName&lt;span style="color:gray;"&gt;,&lt;br /&gt;       &lt;/span&gt;rown &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:magenta;"&gt;row_number&lt;/span&gt;&lt;span style="color:gray;"&gt;() &lt;/span&gt;&lt;span style="color:blue;"&gt;over&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;partition by &lt;/span&gt;LastName &lt;span style="color:blue;"&gt;order by &lt;/span&gt;ContactId&lt;span style="color:gray;"&gt;) &lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;[AdventureWorks]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Person]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Contact] &lt;br /&gt;&lt;span style="color:blue;"&gt;go&lt;br /&gt;Select &lt;/span&gt;&lt;span style="color:gray;"&gt;* &lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;vwContacts  &lt;br /&gt; &lt;span style="color:blue;"&gt;where &lt;/span&gt;LastName &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Smith&amp;#39;&lt;br /&gt; &lt;/span&gt;&lt;span style="color:blue;"&gt;go &lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span style="color:blue;"&gt;&lt;font color="#333333"&gt;You should now see two vastly different query plans &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;&lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/rankingqueryplan1_64817422.jpg"&gt;&lt;img src="http://sqlblogcasts.com/blogs/sqlandthelike/rankingqueryplan1_thumb_5CF604B5.jpg" style="border-width:0px;display:inline;" title="rankingqueryplan1" alt="rankingqueryplan1" width="743" border="0" height="511" /&gt;&lt;/a&gt;&lt;span style="color:blue;"&gt;&lt;font color="#333333"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;Notice in “Query 2” that Filter ?&lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;&lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/image_7C38AB88.png"&gt;&lt;img src="http://sqlblogcasts.com/blogs/sqlandthelike/image_thumb_710F213E.png" style="border-width:0px;display:inline;" title="image" alt="image" width="427" border="0" height="414" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;Wow.. So it did calculate the entire query and then filter on the results.&amp;nbsp; At first i thought that i was being unfair, obviously there is potential for filtering on the ranking function, but when doing exactly the same on 2008 I get index seeks on both sides&lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;&lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/rankingqueryplan2_77C22AC1.jpg"&gt;&lt;img src="http://sqlblogcasts.com/blogs/sqlandthelike/rankingqueryplan2_thumb_294D9857.jpg" style="border-width:0px;display:inline;" title="rankingqueryplan2" alt="rankingqueryplan2" width="732" border="0" height="469" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;CTE’s also suffer from the same problem, although they are easier to rewrite than a view to utilize a seek.&lt;/p&gt;

&lt;p&gt;&lt;span style="color:blue;"&gt;with &lt;/span&gt;cteLastNameRow&lt;span style="color:gray;"&gt;(&lt;/span&gt;ContactId&lt;span style="color:gray;"&gt;,&lt;/span&gt;LastName&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;Row_number&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="color:gray;"&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;as&lt;/span&gt;&lt;span style="color:gray;"&gt;( 
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;select &lt;/span&gt;ContactId&lt;span style="color:gray;"&gt;, 
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;LastName&lt;span style="color:gray;"&gt;, 
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:magenta;"&gt;row_number&lt;/span&gt;&lt;span style="color:gray;"&gt;() &lt;/span&gt;&lt;span style="color:blue;"&gt;over&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;partition by &lt;/span&gt;LastName &lt;span style="color:blue;"&gt;order by &lt;/span&gt;ContactId&lt;span style="color:gray;"&gt;) 
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;[AdventureWorks]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Person]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Contact] 

  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:gray;"&gt;) 
    &lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;select &lt;/span&gt;&lt;span style="color:gray;"&gt;* 
    &lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;cteLastNameRow 

  &lt;br /&gt;&lt;span style="color:blue;"&gt;where &lt;/span&gt;LastName &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Smith&amp;#39; 
    &lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;go&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Another index scan.&lt;/p&gt;

&lt;p&gt;So , be careful when using ranking functions and as ever,&amp;nbsp; investigate the query execution plan on EVERY query. I&amp;#39;ve raised a connect bug report &lt;a href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=488434" target="_blank"&gt;here&lt;/a&gt; if you feel that it is something that Microsoft should invest some time in fixing.&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12247" width="1" height="1"&gt;</content><author><name>Dave Ballantyne</name><uri>http://sqlblogcasts.com/members/Dave-Ballantyne.aspx</uri></author><category term="TSQL" scheme="http://sqlblogcasts.com/blogs/sqlandthelike/archive/tags/TSQL/default.aspx" /><category term="SQLServer" scheme="http://sqlblogcasts.com/blogs/sqlandthelike/archive/tags/SQLServer/default.aspx" /></entry><entry><title>Direct EMailing of SSRS Reports via SQLCLR</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/08/27/direct-emailing-of-ssrs-reports-via-sqlclr.aspx" /><id>http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/08/27/direct-emailing-of-ssrs-reports-via-sqlclr.aspx</id><published>2009-08-27T07:22:02Z</published><updated>2009-08-27T07:22:02Z</updated><content type="html">This is something that I was quite surprised that wasn&amp;#39;t supported out of the tin with SSRS. When you schedule an email delivery, the report is always sent as an attachment. What would be great, if when you specified the render format as &amp;quot;MHTML&amp;quot;, you had the option that the report forms the body of the email. Taking that one step on, how about calling that directly from SQLServer ? Some of which is to follow has been shamelessly ripped from here Source Code here Useage : exec SSRSMail...(&lt;a href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/08/27/direct-emailing-of-ssrs-reports-via-sqlclr.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=12256" width="1" height="1"&gt;</content><author><name>Anonymous</name><uri>http://sqlblogcasts.com/members/Anonymous.aspx</uri></author><category term="SQLServerPedia Syndication" scheme="http://sqlblogcasts.com/blogs/sqlandthelike/archive/tags/SQLServerPedia+Syndication/default.aspx" /><category term="SQL Server" scheme="http://sqlblogcasts.com/blogs/sqlandthelike/archive/tags/SQL+Server/default.aspx" /><category term="SSRS" scheme="http://sqlblogcasts.com/blogs/sqlandthelike/archive/tags/SSRS/default.aspx" /><category term="VB .Net" scheme="http://sqlblogcasts.com/blogs/sqlandthelike/archive/tags/VB+.Net/default.aspx" /><category term="Email" scheme="http://sqlblogcasts.com/blogs/sqlandthelike/archive/tags/Email/default.aspx" /></entry></feed>