<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Alexander Kuznetsov</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Store your configuration settings as a hierarchy in a database.</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/08/24/store-your-configuration-settings-as-a-hierarchy-in-a-database.aspx</link><pubDate>Sun, 24 Aug 2008 21:37:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:8514</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>0</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/8514.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=8514</wfw:commentRss><description>Clearly there are many well known and proven ways to store and maintain the configuration settings of your applications. However, where your requirements have outgrown the ‘off the shelf’ methods, such as Active Directory, the relational database can...(&lt;a href="http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/08/24/store-your-configuration-settings-as-a-hierarchy-in-a-database.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=8514" width="1" height="1"&gt;</description></item><item><title>Performance of inserts and IGNORE_DUP_KEY</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/07/30/performance-of-inserts-and-ignore-dup-key.aspx</link><pubDate>Thu, 31 Jul 2008 02:39:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:8134</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>0</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/8134.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=8134</wfw:commentRss><description>If your data has a small percentage of duplicates, then IGNORE_DUP_KEY may speed up your inserts. For larger amounts of duplicates, IGNORE_DUP_KEY may slow them down significantly. I set up two tables, stripping down all the irrelevant details, as follows:...(&lt;a href="http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/07/30/performance-of-inserts-and-ignore-dup-key.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=8134" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/SQL/default.aspx">SQL</category><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/Database+Programming/default.aspx">Database Programming</category></item><item><title>CPU Overhead for Higher Isolation Levels</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/07/12/cpu-overhead-for-higher-isolation-levels.aspx</link><pubDate>Sun, 13 Jul 2008 01:19:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:7797</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>1</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/7797.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=7797</wfw:commentRss><description>As we know, higher isolation levels acquire more locks and as such they use more CPU, but is the increase significant? In some case the increase is very noticeable, and here are a few benchmarks illustrating my point. Prerequisites: I created the following...(&lt;a href="http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/07/12/cpu-overhead-for-higher-isolation-levels.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=7797" width="1" height="1"&gt;</description></item><item><title>Congratulations, Denis!</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/07/01/congratulations-denis.aspx</link><pubDate>Tue, 01 Jul 2008 17:37:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:7597</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>13</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/7597.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=7597</wfw:commentRss><description>It's great that you are an MVP! Well done! https://mvp.support.microsoft.com/profile=BCCF7416-DA4E-4D73-83E2-65FD61BAB16D Share this post: email it! | bookmark it! | digg it! | reddit! | kick it! | live it!...(&lt;a href="http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/07/01/congratulations-denis.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=7597" width="1" height="1"&gt;</description></item><item><title>Fun with DBCC CHECKIDENT</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/06/26/fun-with-dbcc-chekident.aspx</link><pubDate>Thu, 26 Jun 2008 21:51:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:7531</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>5</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/7531.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=7531</wfw:commentRss><description>&amp;lt;Denis Gobo’s mode on&amp;gt; Suppose you have an empty table: SELECT COUNT (*) FROM SampleTable --- 0 What would be the result of the following query: DBCC CHECKIDENT ( 'SampleTable' , RESEED , 1 ) INSERT SampleTable ( j ) SELECT 1 SELECT SCOPE_IDENTITY...(&lt;a href="http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/06/26/fun-with-dbcc-chekident.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=7531" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/Database+Unit+Testing/default.aspx">Database Unit Testing</category><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/Database+Testing/default.aspx">Database Testing</category><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/Database+Programming/default.aspx">Database Programming</category></item><item><title>Database Unit Testing: Impersonation</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/06/18/database-unit-testing-impersonation.aspx</link><pubDate>Wed, 18 Jun 2008 16:19:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:7367</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>1</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/7367.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=7367</wfw:commentRss><description>When you run NUnit/C# unit tests against your local instance, you are a dbo. As such, you are not getting any errors caused by missing permissions. However, you can impersonate another user, and run your unit tests in the context of that other user. The...(&lt;a href="http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/06/18/database-unit-testing-impersonation.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=7367" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/Impersonation/default.aspx">Impersonation</category><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/Database+Unit+Testing/default.aspx">Database Unit Testing</category><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/Database+Testing/default.aspx">Database Testing</category></item><item><title>Unit Testing Tips: Reproduce a Lock Timeout</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/30/unit-testing-tips-reproduce-a-lock-timeout.aspx</link><pubDate>Fri, 30 May 2008 22:24:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:7086</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>0</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/7086.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=7086</wfw:commentRss><description>Well, I have just finished a series of articles about unit testing on simple-talk.com, and some techniques were not included, just to keep the articles short. Still problems such as reproducing a lock timeout and unit testing the retry after it (lock...(&lt;a href="http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/30/unit-testing-tips-reproduce-a-lock-timeout.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=7086" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/Database+Unit+Testing/default.aspx">Database Unit Testing</category><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/Database+Testing/default.aspx">Database Testing</category></item><item><title>Reuse Your Code with Table-Valued UDFs</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/23/reuse-your-code-with-cross-apply.aspx</link><pubDate>Fri, 23 May 2008 17:26:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:6942</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>9</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/6942.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=6942</wfw:commentRss><description>
&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;Suppose you are using SQL Server 2005, and you want to
truncate your DATETIME value, leaving only date part of it, as follows:&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:fuchsia;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:fuchsia;"&gt;DATEADD&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;(&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:fuchsia;"&gt;day&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:fuchsia;"&gt;DATEDIFF&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;day&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:red;"&gt;'19010101'&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; LastModifiedDate&lt;span style="color:gray;"&gt;),&lt;/span&gt; &lt;span style="color:red;"&gt;'19010101'&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Suppose you want to reuse this code and wrap it in a scalar
UDF:&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;CREATE&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;FUNCTION&lt;/span&gt;
dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;TruncatedDateTime&lt;span style="color:gray;"&gt;(&lt;/span&gt;@d
&lt;span style="color:blue;"&gt;DATETIME&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;RETURNS&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;DATETIME&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;AS&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;BEGIN&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;RETURN&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:fuchsia;"&gt;DATEADD&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;day&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:fuchsia;"&gt;DATEDIFF&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;day&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:red;"&gt;'19010101'&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; @d&lt;span style="color:gray;"&gt;),&lt;/span&gt; &lt;span style="color:red;"&gt;'19010101'&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;END&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;GO&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;It is well known that scalar UDFs may be slow, but how slow
is this particular one, as compared to the expression which it wraps? That’s
quite easy to figure out. I populated a table with one million dates from one
of my production tables, as follows:&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;TOP&lt;/span&gt;
1000000 LastModifiedDate &lt;span style="color:blue;"&gt;INTO&lt;/span&gt; dates &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;FROM&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; data&lt;span style="color:gray;"&gt;.&lt;/span&gt;MyProductionTable&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;And I ran these two queries:&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:fuchsia;"&gt;COUNT&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:gray;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:fuchsia;"&gt;DATEADD&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;day&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:fuchsia;"&gt;DATEDIFF&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;day&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:red;"&gt;'19010101'&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; LastModifiedDate&lt;span style="color:gray;"&gt;),&lt;/span&gt; &lt;span style="color:red;"&gt;'19010101'&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; d &lt;span style="color:blue;"&gt;FROM&lt;/span&gt; dates&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;)&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; t &lt;span style="color:blue;"&gt;WHERE&lt;/span&gt;
d&lt;span style="color:gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:red;"&gt;'20220203'&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:red;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-family:'Courier New';color:red;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-family:'Courier New';"&gt;(snip)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;SQL &lt;span style="color:blue;"&gt;Server&lt;/span&gt;
Execution Times&lt;span style="color:gray;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CPU &lt;span style="color:blue;"&gt;time&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; 343 ms&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;elapsed &lt;span style="color:blue;"&gt;time&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; 347 ms&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:fuchsia;"&gt;COUNT&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:gray;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;TruncatedDateTime&lt;span style="color:gray;"&gt;(&lt;/span&gt;LastModifiedDate&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; d &lt;span style="color:blue;"&gt;FROM&lt;/span&gt; Dates&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;)&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; t &lt;span style="color:blue;"&gt;WHERE&lt;/span&gt;
d&lt;span style="color:gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:red;"&gt;'20220203'&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:red;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-family:'Courier New';color:red;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;(snip)&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;SQL &lt;span style="color:blue;"&gt;Server&lt;/span&gt;
Execution Times&lt;span style="color:gray;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CPU &lt;span style="color:blue;"&gt;time&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; 26109 ms&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;elapsed &lt;span style="color:blue;"&gt;time&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; 26651 ms&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Note that the UDF slowed the query down almost one thousand
times, as expected. However, let us consider a better alternative – a &lt;span&gt;&amp;nbsp;&lt;/span&gt;table-valued UDF, as follows:&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;CREATE&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;FUNCTION&lt;/span&gt;
dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;TableValuedTruncatedDateTime&lt;span style="color:gray;"&gt;(&lt;/span&gt;@d &lt;span style="color:blue;"&gt;DATETIME&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;RETURNS&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;TABLE&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;AS&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;RETURN&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;(&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;SELECT&lt;/span&gt;
&lt;span style="color:fuchsia;"&gt;DATEADD&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;day&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:fuchsia;"&gt;DATEDIFF&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;day&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:red;"&gt;'19010101'&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; @d&lt;span style="color:gray;"&gt;),&lt;/span&gt; &lt;span style="color:red;"&gt;'19010101'&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt;
TruncatedDateTime&lt;span style="color:gray;"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;GO&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:fuchsia;"&gt;COUNT&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:gray;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; TruncatedDateTime &lt;span style="color:blue;"&gt;AS&lt;/span&gt; d &lt;span style="color:blue;"&gt;FROM&lt;/span&gt; Dates &lt;span style="color:gray;"&gt;CROSS&lt;/span&gt; &lt;span style="color:gray;"&gt;APPLY&lt;/span&gt; dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;TableValuedTruncatedDateTime&lt;span style="color:gray;"&gt;(&lt;/span&gt;Dates&lt;span style="color:gray;"&gt;.&lt;/span&gt;LastModifiedDate&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;)&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; t &lt;span style="color:blue;"&gt;WHERE&lt;/span&gt;
d&lt;span style="color:gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:red;"&gt;'20220203'&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:red;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;(snip)&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;SQL &lt;span style="color:blue;"&gt;Server&lt;/span&gt;
Execution Times&lt;span style="color:gray;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CPU &lt;span style="color:blue;"&gt;time&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; 344 ms&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;elapsed &lt;span style="color:blue;"&gt;time&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; 347 ms&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Note that the query using the table-valued UDF runs just as
fast as the original one. As you have seen, CROSS APPLY allowed you to reuse
your date-truncating code without taking a performance hit.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Reuse Your Code with Table-Valued UDFs&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Reuse Your Code with Table-Valued UDFs%0A%0Ahttp://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/23/reuse-your-code-with-cross-apply.aspx" target="_blank" title = "Email Reuse Your Code with Table-Valued UDFs"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/23/reuse-your-code-with-cross-apply.aspx&amp;amp;title=Reuse+Your+Code+with+Table-Valued+UDFs" target="_blank" title = "Submit Reuse Your Code with Table-Valued UDFs to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/23/reuse-your-code-with-cross-apply.aspx&amp;amp;phase=2" target="_blank" title = "Submit Reuse Your Code with Table-Valued UDFs to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/23/reuse-your-code-with-cross-apply.aspx&amp;amp;title=Reuse+Your+Code+with+Table-Valued+UDFs" target="_blank" title = "Submit Reuse Your Code with Table-Valued UDFs to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/23/reuse-your-code-with-cross-apply.aspx&amp;amp;title=Reuse+Your+Code+with+Table-Valued+UDFs" target="_blank" title = "Submit Reuse Your Code with Table-Valued UDFs to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/23/reuse-your-code-with-cross-apply.aspx&amp;amp;title=Reuse+Your+Code+with+Table-Valued+UDFs&amp;amp;;top=1" target="_blank" title = "Add Reuse Your Code with Table-Valued UDFs to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6942" width="1" height="1"&gt;</description></item><item><title>A Great Advice on Coding Predicates in Outer Joins</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/15/a-great-advice-on-coding-predicates-in-outer-joins.aspx</link><pubDate>Thu, 15 May 2008 17:19:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:6804</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>0</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/6804.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=6804</wfw:commentRss><description>&lt;p&gt;Yet another very common error is when someone puts a wrong condition in a WHERE clause and that essentially renders an outer join into an inner join. A great advice on coding predicates in outer joins comes from a DB2 expert Terry Purcell.&lt;/p&gt;&lt;p&gt;"Meet the experts: Terry Purcell on coding predicates in outer joins: A comparison of simple outer join constructs"&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.ibm.com/developerworks/db2/library/techarticle/purcell/0112purcell.html"&gt;http://www.ibm.com/developerworks/db2/library/techarticle/purcell/0112purcell.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Enjoy!&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=A Great Advice on Coding Predicates in Outer Joins&amp;amp;body=Seen on SQLblog.com: %0A%0A%09A Great Advice on Coding Predicates in Outer Joins%0A%0Ahttp://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/15/a-great-advice-on-coding-predicates-in-outer-joins.aspx" target="_blank" title = "Email A Great Advice on Coding Predicates in Outer Joins"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/15/a-great-advice-on-coding-predicates-in-outer-joins.aspx&amp;amp;title=A+Great+Advice+on+Coding+Predicates+in+Outer+Joins" target="_blank" title = "Submit A Great Advice on Coding Predicates in Outer Joins to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/15/a-great-advice-on-coding-predicates-in-outer-joins.aspx&amp;amp;phase=2" target="_blank" title = "Submit A Great Advice on Coding Predicates in Outer Joins to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/15/a-great-advice-on-coding-predicates-in-outer-joins.aspx&amp;amp;title=A+Great+Advice+on+Coding+Predicates+in+Outer+Joins" target="_blank" title = "Submit A Great Advice on Coding Predicates in Outer Joins to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/15/a-great-advice-on-coding-predicates-in-outer-joins.aspx&amp;amp;title=A+Great+Advice+on+Coding+Predicates+in+Outer+Joins" target="_blank" title = "Submit A Great Advice on Coding Predicates in Outer Joins to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/15/a-great-advice-on-coding-predicates-in-outer-joins.aspx&amp;amp;title=A+Great+Advice+on+Coding+Predicates+in+Outer+Joins&amp;amp;;top=1" target="_blank" title = "Add A Great Advice on Coding Predicates in Outer Joins to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6804" width="1" height="1"&gt;</description></item><item><title>Be Aware of These Loopholes in Your Referential Integrity</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/13/be-aware-of-these-loopholes-in-your-referential-integrity.aspx</link><pubDate>Tue, 13 May 2008 22:17:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:6783</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>1</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/6783.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=6783</wfw:commentRss><description>

&lt;p class="MsoNormal"&gt;I am going to discuss several potential problems with referential
integrity, because they keep coming up in the newsgroups.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b&gt;Parent and Child Tables
Are in Different Databases.&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;Although you cannot use a foreign key in this situation,
there are workarounds – you can use either triggers or UDFs wrapped in check
constraints. Either way, your data integrity is not completely watertight: if
the database with your parent table crashes and you restore it from a backup,
you may easily end up with orphans.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b&gt;Parent-Child Relationship
Is Enforced by Triggers.&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;There are quite a few situations when triggers do not fire,
such as:&lt;/p&gt;

&lt;p class="MsoListParagraphCxSpFirst" style="text-indent:-0.25in;"&gt;&lt;span style="font-family:Symbol;"&gt;&lt;span&gt;·&lt;span style="font-family:'Times New Roman';font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;A table is dropped.&lt;/p&gt;

&lt;p class="MsoListParagraphCxSpMiddle" style="text-indent:-0.25in;"&gt;&lt;span style="font-family:Symbol;"&gt;&lt;span&gt;·&lt;span style="font-family:'Times New Roman';font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;A table is truncated.&lt;/p&gt;

&lt;p class="MsoListParagraphCxSpLast" style="text-indent:-0.25in;"&gt;&lt;span style="font-family:Symbol;"&gt;&lt;span&gt;·&lt;span style="font-family:'Times New Roman';font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Settings for nested and/or recursive triggers
prevent a trigger from firing.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Also a trigger may be just incorrect. Either way, you may
end up with orphans in your database.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b&gt;Parent-Child Relationship
Is Enforced by UDFs Wrapped in Check Constraints.&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;Such “constraints” do not prevent from deleting parent rows.
Again, you may end up with orphans in your database.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;In most cases the easiest and simplest way to enforce a
parent-child relationship is to use a built-in tool – do not reinvent the wheel,
have both tables in one database and use a foreign key.&lt;/p&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Be Aware of These Loopholes in Your Referential Integrity&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Be Aware of These Loopholes in Your Referential Integrity%0A%0Ahttp://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/13/be-aware-of-these-loopholes-in-your-referential-integrity.aspx" target="_blank" title = "Email Be Aware of These Loopholes in Your Referential Integrity"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/13/be-aware-of-these-loopholes-in-your-referential-integrity.aspx&amp;amp;title=Be+Aware+of+These+Loopholes+in+Your+Referential+Integrity" target="_blank" title = "Submit Be Aware of These Loopholes in Your Referential Integrity to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/13/be-aware-of-these-loopholes-in-your-referential-integrity.aspx&amp;amp;phase=2" target="_blank" title = "Submit Be Aware of These Loopholes in Your Referential Integrity to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/13/be-aware-of-these-loopholes-in-your-referential-integrity.aspx&amp;amp;title=Be+Aware+of+These+Loopholes+in+Your+Referential+Integrity" target="_blank" title = "Submit Be Aware of These Loopholes in Your Referential Integrity to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/13/be-aware-of-these-loopholes-in-your-referential-integrity.aspx&amp;amp;title=Be+Aware+of+These+Loopholes+in+Your+Referential+Integrity" target="_blank" title = "Submit Be Aware of These Loopholes in Your Referential Integrity to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/13/be-aware-of-these-loopholes-in-your-referential-integrity.aspx&amp;amp;title=Be+Aware+of+These+Loopholes+in+Your+Referential+Integrity&amp;amp;;top=1" target="_blank" title = "Add Be Aware of These Loopholes in Your Referential Integrity to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6783" width="1" height="1"&gt;</description></item><item><title>When Index Covering Prevents Deadlocks</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/03/when-index-covering-prevents-deadlocks.aspx</link><pubDate>Sun, 04 May 2008 03:08:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:6611</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>4</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/6611.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=6611</wfw:commentRss><description>
&lt;p class="MsoNormal"&gt;Suppose that a select has just navigated all the way down a
non-clustered index and is trying to lookup a row in the clustered index.
Suppose that at the same time an update has just modified that row and tries to
modify the corresponding entry in the non-clustered index. This situation will
end up in a deadlock. However, if the non-clustered index covers the select
query, once the select has navigated to the leaf level of that index, there is
no need to perform a bookmark lookup. As such, this select will not embrace in
a deadlock. (Note that situations like this are intermittent – they happen from
time to time, but not every time you run your select. &lt;/p&gt;

&lt;p class="MsoNormal"&gt;To reproduce this quite common situation, I created the
following table and index:&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;CREATE&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;TABLE&lt;/span&gt;
[dbo]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Tickets]&lt;span style="color:gray;"&gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[TicketId] [int] &lt;span style="color:gray;"&gt;NOT&lt;/span&gt; &lt;span style="color:gray;"&gt;NULL,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[AssignedTo] [int]
&lt;span style="color:gray;"&gt;NOT&lt;/span&gt; &lt;span style="color:gray;"&gt;NULL,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[Priority]
[varchar]&lt;span style="color:gray;"&gt;(&lt;/span&gt;10&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;COLLATE&lt;/span&gt; SQL_Latin1_General_CP1_CI_AS &lt;span style="color:gray;"&gt;NOT&lt;/span&gt; &lt;span style="color:gray;"&gt;NULL,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[Status] [varchar]&lt;span style="color:gray;"&gt;(&lt;/span&gt;10&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;COLLATE&lt;/span&gt; SQL_Latin1_General_CP1_CI_AS &lt;span style="color:gray;"&gt;NOT&lt;/span&gt; &lt;span style="color:gray;"&gt;NULL,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[LotsOfComments]
[char]&lt;span style="color:gray;"&gt;(&lt;/span&gt;5000&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;COLLATE&lt;/span&gt; SQL_Latin1_General_CP1_CI_AS &lt;span style="color:gray;"&gt;NOT&lt;/span&gt; &lt;span style="color:gray;"&gt;NULL,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:blue;"&gt;CONSTRAINT&lt;/span&gt; [PK_Tickets] &lt;span style="color:blue;"&gt;PRIMARY&lt;/span&gt;
&lt;span style="color:blue;"&gt;KEY&lt;/span&gt; &lt;span style="color:blue;"&gt;CLUSTERED&lt;/span&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:gray;"&gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[TicketId] &lt;span style="color:blue;"&gt;ASC&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:gray;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:gray;"&gt;)&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;ON&lt;/span&gt; [PRIMARY]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;GO&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;CREATE&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;NONCLUSTERED&lt;/span&gt;
&lt;span style="color:blue;"&gt;INDEX&lt;/span&gt; [NCI_Tickets_AssignedTo] &lt;span style="color:blue;"&gt;ON&lt;/span&gt; [dbo]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Tickets] &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:gray;"&gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[AssignedTo] &lt;span style="color:blue;"&gt;ASC&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:gray;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;GO&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;I populated the table with 10K rows, and simultaneously ran
the following update:&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;UPDATE&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; Data&lt;span style="color:gray;"&gt;.&lt;/span&gt;Tickets
&lt;span style="color:blue;"&gt;SET&lt;/span&gt; AssignedTo &lt;span style="color:gray;"&gt;=&lt;/span&gt;
1 &lt;span style="color:blue;"&gt;WHERE&lt;/span&gt; TicketId &lt;span style="color:gray;"&gt;=&lt;/span&gt;
1&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;SET&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;NOCOUNT&lt;/span&gt;
&lt;span style="color:blue;"&gt;ON&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;DECLARE&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; @i &lt;span style="color:blue;"&gt;INT&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; @Status &lt;span style="color:blue;"&gt;VARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;10&lt;span style="color:gray;"&gt;),&lt;/span&gt; @TicketId &lt;span style="color:blue;"&gt;INT&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;SET&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; @i &lt;span style="color:gray;"&gt;=&lt;/span&gt;
0&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;WHILE&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; @i &lt;span style="color:gray;"&gt;&amp;lt;&lt;/span&gt;
100000 &lt;span style="color:blue;"&gt;BEGIN&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT&lt;/span&gt; @i &lt;span style="color:gray;"&gt;=&lt;/span&gt; @i &lt;span style="color:gray;"&gt;+&lt;/span&gt; 1&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:green;"&gt;-- because originally AssignedTo = 1 for this
row,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:green;"&gt;-- it will toggle 0,1,0,1,0,1,0,1&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;UPDATE&lt;/span&gt; Data&lt;span style="color:gray;"&gt;.&lt;/span&gt;Tickets &lt;span style="color:blue;"&gt;SET&lt;/span&gt; AssignedTo &lt;span style="color:gray;"&gt;=&lt;/span&gt; 1 &lt;span style="color:gray;"&gt;-&lt;/span&gt; AssignedTo &lt;span style="color:blue;"&gt;WHERE&lt;/span&gt;
TicketId &lt;span style="color:gray;"&gt;=&lt;/span&gt; 1&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;END&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;And I ran the following select in another tab of SSMS:&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;DECLARE&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; @i &lt;span style="color:blue;"&gt;INT&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; @Status &lt;span style="color:blue;"&gt;VARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;10&lt;span style="color:gray;"&gt;),&lt;/span&gt; @AssignedTo &lt;span style="color:blue;"&gt;INT&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;SET&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; @i &lt;span style="color:gray;"&gt;=&lt;/span&gt;
0&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;WHILE&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; @i &lt;span style="color:gray;"&gt;&amp;lt;&lt;/span&gt;
1000000 &lt;span style="color:blue;"&gt;BEGIN&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT&lt;/span&gt; @i &lt;span style="color:gray;"&gt;=&lt;/span&gt; @i &lt;span style="color:gray;"&gt;+&lt;/span&gt; 1&lt;span style="color:gray;"&gt;,&lt;/span&gt; @Status &lt;span style="color:gray;"&gt;=&lt;/span&gt; Status&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;FROM&lt;/span&gt; Data&lt;span style="color:gray;"&gt;.&lt;/span&gt;Tickets &lt;span style="color:blue;"&gt;WHERE&lt;/span&gt; AssignedTo &lt;span style="color:gray;"&gt;=&lt;/span&gt; 1&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;END&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Every time I run these two scripts, the select consistently
becomes a deadlock victim in just a few seconds. Let us use index covering:&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;DROP&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;INDEX&lt;/span&gt;
[Data]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Tickets]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Tickets_AssignedTo]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:blue;"&gt;CREATE&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;NONCLUSTERED&lt;/span&gt;
&lt;span style="color:blue;"&gt;INDEX&lt;/span&gt; [Tickets_AssignedTo] &lt;span style="color:blue;"&gt;ON&lt;/span&gt; [Data]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Tickets] &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:gray;"&gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[AssignedTo]&lt;span style="color:gray;"&gt;,&lt;/span&gt; Status&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';color:gray;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';"&gt;GO&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Now both scripts complete without deadlocks, although they usually
run simultaneously for more than 30 seconds on my laptop.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;As you have seen, in this particular case index covering
completely eliminated deadlocks. Of course, real life situations are usually
much more complex than this simplistic one.&lt;/p&gt;&lt;p class="MsoNormal"&gt;PS As Uri pointed out, it is necessary to compare the outcome for different isolation levels. So, if I up the isolation level to repeatable read or to serializable, I am still getting deadlocks. Uri was right, the TABLOCK hint prevents deadlocks but slows the execution down significantly. Also there are no deadlocks under snapshot isolation - we could guess that much ;).&lt;br&gt;&lt;/p&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=When Index Covering Prevents Deadlocks&amp;amp;body=Seen on SQLblog.com: %0A%0A%09When Index Covering Prevents Deadlocks%0A%0Ahttp://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/03/when-index-covering-prevents-deadlocks.aspx" target="_blank" title = "Email When Index Covering Prevents Deadlocks"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/03/when-index-covering-prevents-deadlocks.aspx&amp;amp;title=When+Index+Covering+Prevents+Deadlocks" target="_blank" title = "Submit When Index Covering Prevents Deadlocks to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/03/when-index-covering-prevents-deadlocks.aspx&amp;amp;phase=2" target="_blank" title = "Submit When Index Covering Prevents Deadlocks to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/03/when-index-covering-prevents-deadlocks.aspx&amp;amp;title=When+Index+Covering+Prevents+Deadlocks" target="_blank" title = "Submit When Index Covering Prevents Deadlocks to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/03/when-index-covering-prevents-deadlocks.aspx&amp;amp;title=When+Index+Covering+Prevents+Deadlocks" target="_blank" title = "Submit When Index Covering Prevents Deadlocks to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/05/03/when-index-covering-prevents-deadlocks.aspx&amp;amp;title=When+Index+Covering+Prevents+Deadlocks&amp;amp;;top=1" target="_blank" title = "Add When Index Covering Prevents Deadlocks to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6611" width="1" height="1"&gt;</description></item><item><title>Not all UDFs are bad for performance.</title><link>http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/04/21/not-all-udfs-are-bad-for-performance.aspx</link><pubDate>Mon, 21 Apr 2008 22:43:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:6330</guid><dc:creator>Alexander Kuznetsov</dc:creator><slash:comments>3</slash:comments><comments>http://sqlblog.com/blogs/alexander_kuznetsov/comments/6330.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/alexander_kuznetsov/commentrss.aspx?PostID=6330</wfw:commentRss><description>&lt;p class="MsoNormal"&gt;There is a popular misconception that UDFs have adverse
effect on performance. As a blanket statement, this is simply not true. In
fact, inline table-valued UDFs are actually macros – the optimizer is very well
capable rewriting queries involving them as well as optimizing them. However,
scalar UDFs are usually &lt;span&gt;&amp;nbsp;&lt;/span&gt;very slow. &lt;span&gt;&amp;nbsp;&lt;/span&gt;I will provide a short example.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b&gt;Prerequisites&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;Here is the script to create and populate the tables:&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;CREATE&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;TABLE&lt;/span&gt;
States&lt;span style="color:gray;"&gt;(&lt;/span&gt;Code &lt;span style="color:blue;"&gt;CHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;2&lt;span style="color:gray;"&gt;),&lt;/span&gt; [Name] &lt;span style="color:blue;"&gt;VARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;40&lt;span style="color:gray;"&gt;),&lt;/span&gt; &lt;span style="color:blue;"&gt;CONSTRAINT&lt;/span&gt;
PK_States &lt;span style="color:blue;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:blue;"&gt;KEY&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Code&lt;span style="color:gray;"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;GO&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;INSERT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; States&lt;span style="color:gray;"&gt;(&lt;/span&gt;Code&lt;span style="color:gray;"&gt;,&lt;/span&gt; [Name]&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:red;"&gt;'IL'&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:red;"&gt;'Illinois'&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;INSERT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; States&lt;span style="color:gray;"&gt;(&lt;/span&gt;Code&lt;span style="color:gray;"&gt;,&lt;/span&gt; [Name]&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:red;"&gt;'WI'&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:red;"&gt;'Wisconsin'&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;INSERT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; States&lt;span style="color:gray;"&gt;(&lt;/span&gt;Code&lt;span style="color:gray;"&gt;,&lt;/span&gt; [Name]&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:red;"&gt;'IA'&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:red;"&gt;'Iowa'&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;INSERT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; States&lt;span style="color:gray;"&gt;(&lt;/span&gt;Code&lt;span style="color:gray;"&gt;,&lt;/span&gt; [Name]&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:red;"&gt;'IN'&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:red;"&gt;'Indiana'&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;INSERT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; States&lt;span style="color:gray;"&gt;(&lt;/span&gt;Code&lt;span style="color:gray;"&gt;,&lt;/span&gt; [Name]&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;VALUES&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:red;"&gt;'MI'&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:red;"&gt;'Michigan'&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;GO&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;CREATE&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;TABLE&lt;/span&gt;
Observations&lt;span style="color:gray;"&gt;(&lt;/span&gt;ID &lt;span style="color:blue;"&gt;INT&lt;/span&gt;
&lt;span style="color:gray;"&gt;NOT&lt;/span&gt; &lt;span style="color:gray;"&gt;NULL,&lt;/span&gt;
StateCode &lt;span style="color:blue;"&gt;CHAR&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:blue;"&gt;CONSTRAINT&lt;/span&gt;
PK_Observations &lt;span style="color:blue;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:blue;"&gt;KEY&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;ID&lt;span style="color:gray;"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;GO&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SET&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;NOCOUNT&lt;/span&gt;
&lt;span style="color:blue;"&gt;ON&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;DECLARE&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; @i &lt;span style="color:blue;"&gt;INT&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SET&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; @i&lt;span style="color:gray;"&gt;=&lt;/span&gt;0&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;WHILE&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; @i&lt;span style="color:gray;"&gt;&amp;lt;&lt;/span&gt;100000
&lt;span style="color:blue;"&gt;BEGIN&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;SET&lt;/span&gt; @i &lt;span style="color:gray;"&gt;=&lt;/span&gt; @i &lt;span style="color:gray;"&gt;+&lt;/span&gt; 1&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;INSERT&lt;/span&gt;
Observations&lt;span style="color:gray;"&gt;(&lt;/span&gt;ID&lt;span style="color:gray;"&gt;,&lt;/span&gt;
StateCode&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT&lt;/span&gt; @i&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:blue;"&gt;CASE&lt;/span&gt; &lt;span style="color:blue;"&gt;WHEN&lt;/span&gt; @i &lt;span style="color:gray;"&gt;%&lt;/span&gt; 5 &lt;span style="color:gray;"&gt;=&lt;/span&gt; 0 &lt;span style="color:blue;"&gt;THEN&lt;/span&gt; &lt;span style="color:red;"&gt;'IL'&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:red;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;WHEN&lt;/span&gt; @i &lt;span style="color:gray;"&gt;%&lt;/span&gt; 5 &lt;span style="color:gray;"&gt;=&lt;/span&gt; 1 &lt;span style="color:blue;"&gt;THEN&lt;/span&gt; &lt;span style="color:red;"&gt;'IA'&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:red;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;WHEN&lt;/span&gt; @i &lt;span style="color:gray;"&gt;%&lt;/span&gt; 5 &lt;span style="color:gray;"&gt;=&lt;/span&gt; 2 &lt;span style="color:blue;"&gt;THEN&lt;/span&gt; &lt;span style="color:red;"&gt;'WI'&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:red;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;WHEN&lt;/span&gt; @i &lt;span style="color:gray;"&gt;%&lt;/span&gt; 5 &lt;span style="color:gray;"&gt;=&lt;/span&gt; 3 &lt;span style="color:blue;"&gt;THEN&lt;/span&gt; &lt;span style="color:red;"&gt;'IA'&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:red;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;WHEN&lt;/span&gt; @i &lt;span style="color:gray;"&gt;%&lt;/span&gt; 5 &lt;span style="color:gray;"&gt;=&lt;/span&gt; 4 &lt;span style="color:blue;"&gt;THEN&lt;/span&gt; &lt;span style="color:red;"&gt;'MI'&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:red;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;END&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;END&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;GO&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;When a query
involving a UDF is rewritten as an outer join.&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;Consider the following query:&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; o&lt;span style="color:gray;"&gt;.&lt;/span&gt;ID&lt;span style="color:gray;"&gt;,&lt;/span&gt; s&lt;span style="color:gray;"&gt;.&lt;/span&gt;[name] &lt;span style="color:blue;"&gt;AS&lt;/span&gt; StateName &lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;INTO&lt;/span&gt; dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;ObservationsWithStateNames_Join&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;FROM&lt;/span&gt; dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;Observations o &lt;span style="color:gray;"&gt;LEFT&lt;/span&gt; &lt;span style="color:gray;"&gt;OUTER&lt;/span&gt; &lt;span style="color:gray;"&gt;JOIN&lt;/span&gt; dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;States s &lt;span style="color:blue;"&gt;ON&lt;/span&gt; o&lt;span style="color:gray;"&gt;.&lt;/span&gt;StateCode &lt;span style="color:gray;"&gt;=&lt;/span&gt; s&lt;span style="color:gray;"&gt;.&lt;/span&gt;Code&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;/*&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;SQL Server parse
and compile time: &lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CPU time = 0 ms, elapsed time = 1 ms.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;Table
'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads
0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;Table
'Observations'. Scan count 1, logical reads 188, physical reads 0, read-ahead
reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;Table 'States'.
Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob
logical reads 0, lob physical reads 0, lob read-ahead reads 0.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;SQL Server
Execution Times:&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CPU time = 187 ms,&lt;span&gt;&amp;nbsp; &lt;/span&gt;elapsed time = 188 ms.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;*/&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;And compare it to a query involving an inline table valued
UDF:&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;CREATE&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;FUNCTION&lt;/span&gt;
dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;GetStateName_Inline&lt;span style="color:gray;"&gt;(&lt;/span&gt;@StateCode
&lt;span style="color:blue;"&gt;CHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;2&lt;span style="color:gray;"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;RETURNS&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;TABLE&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;AS&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;RETURN&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;(&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; [Name] &lt;span style="color:blue;"&gt;FROM&lt;/span&gt; dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;States &lt;span style="color:blue;"&gt;WHERE&lt;/span&gt; Code &lt;span style="color:gray;"&gt;=&lt;/span&gt;
@StateCode&lt;span style="color:gray;"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;GO&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; ID&lt;span style="color:gray;"&gt;,&lt;/span&gt;
&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT&lt;/span&gt; [name] &lt;span style="color:blue;"&gt;FROM&lt;/span&gt; dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;GetStateName_Inline&lt;span style="color:gray;"&gt;(&lt;/span&gt;StateCode&lt;span style="color:gray;"&gt;))&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; StateName &lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;INTO&lt;/span&gt; dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;ObservationsWithStateNames_Inline&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;FROM&lt;/span&gt; dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;Observations&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Both its execution plan and its execution costs are the same
– the optimizer has rewritten it as an outer join. Don’t underestimate the
power of the optimizer! &lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b&gt;A query involving a
scalar UDF is much slower.&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;Here is a scalar UDF:&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;CREATE&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;FUNCTION&lt;/span&gt;
dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;GetStateName&lt;span style="color:gray;"&gt;(&lt;/span&gt;@StateCode
&lt;span style="color:blue;"&gt;CHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;2&lt;span style="color:gray;"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;RETURNS&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt; &lt;span style="color:blue;"&gt;VARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;40&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;AS&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;BEGIN&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;DECLARE&lt;/span&gt; @ret &lt;span style="color:blue;"&gt;VARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;40&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;SET&lt;/span&gt; @ret &lt;span style="color:gray;"&gt;=&lt;/span&gt; &lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT&lt;/span&gt; [Name] &lt;span style="color:blue;"&gt;FROM&lt;/span&gt;
dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;States &lt;span style="color:blue;"&gt;WHERE&lt;/span&gt;
Code &lt;span style="color:gray;"&gt;=&lt;/span&gt; @StateCode&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:gray;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;RETURN&lt;/span&gt; @ret&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;END&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';"&gt;GO&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Clearly the query using this UDF provides the same results
but it has a different execution plan and it is dramatically slower:&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;/*&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;SQL Server parse
and compile time: &lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CPU time = 0 ms, elapsed time = 3 ms.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;Table
'Worktable'. Scan count 1, logical reads 202930, physical reads 0, read-ahead
reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;Table
'Observations'. Scan count 1, logical reads 188, physical reads 0, read-ahead
reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;SQL Server
Execution Times:&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CPU time = 11890 ms,&lt;span&gt;&amp;nbsp; &lt;/span&gt;elapsed time = 38585 ms.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-family:'Courier New';color:green;"&gt;*/&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;As you have seen, the optimizer can rewrite and optimize
queries involving inline table valued UDFs. On the other hand, queries
involving scalar UDFs are not rewritten by the optimizer – the execution of the
last query includes one function call per row, which is very slow.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;Also thank you Peter and Adam for setting me up as a blogger on this wonderful site!&lt;br&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;BR&gt;&lt;div class = "shareblock"&gt;&lt;span class = "shareblockTitle"&gt;Share this post:&lt;/span&gt;&lt;span class = "shareblockLink"&gt; &lt;a href = "mailto:?subject=Not all UDFs are bad for performance.&amp;amp;body=Seen on SQLblog.com: %0A%0A%09Not all UDFs are bad for performance.%0A%0Ahttp://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/04/21/not-all-udfs-are-bad-for-performance.aspx" target="_blank" title = "Email Not all UDFs are bad for performance."&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/04/21/not-all-udfs-are-bad-for-performance.aspx&amp;amp;title=Not+all+UDFs+are+bad+for+performance." target="_blank" title = "Submit Not all UDFs are bad for performance. to del.icio.us"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/04/21/not-all-udfs-are-bad-for-performance.aspx&amp;amp;phase=2" target="_blank" title = "Submit Not all UDFs are bad for performance. to digg.com"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/04/21/not-all-udfs-are-bad-for-performance.aspx&amp;amp;title=Not+all+UDFs+are+bad+for+performance." target="_blank" title = "Submit Not all UDFs are bad for performance. to reddit.com"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/04/21/not-all-udfs-are-bad-for-performance.aspx&amp;amp;title=Not+all+UDFs+are+bad+for+performance." target="_blank" title = "Submit Not all UDFs are bad for performance. to DotNetKicks"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/04/21/not-all-udfs-are-bad-for-performance.aspx&amp;amp;title=Not+all+UDFs+are+bad+for+performance.&amp;amp;;top=1" target="_blank" title = "Add Not all UDFs are bad for performance. to Live Bookmarks"&gt;live it!&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://info.sqlblog.com/a.aspx?ZoneID=0&amp;BannerID=12&amp;AdvertiserID=1&amp;CampaignID=12&amp;Task=Get&amp;Mode=TEXT&amp;SiteID=1&amp;RandomNumber=463323" width="1" height="1" border="0"&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6330" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/alexander_kuznetsov/archive/tags/SQL+Server/default.aspx">SQL Server</category></item></channel></rss>