<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>TDD developer &#187; Query execution plan</title>
	<atom:link href="http://testdrivendevelopment.wordpress.com/tag/query-execution-plan/feed/" rel="self" type="application/rss+xml" />
	<link>http://testdrivendevelopment.wordpress.com</link>
	<description>Diary of an agile developer</description>
	<lastBuildDate>Wed, 28 Oct 2009 22:06:05 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='testdrivendevelopment.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/a6ef45b2d30fa0fcbe697fa111d46fdd?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>TDD developer &#187; Query execution plan</title>
		<link>http://testdrivendevelopment.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://testdrivendevelopment.wordpress.com/osd.xml" title="TDD developer" />
		<item>
		<title>NHibernate queries &amp; sql server execution plans</title>
		<link>http://testdrivendevelopment.wordpress.com/2009/03/10/nhibernate-queries-sql-server-execution-plans/</link>
		<comments>http://testdrivendevelopment.wordpress.com/2009/03/10/nhibernate-queries-sql-server-execution-plans/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 20:57:06 +0000</pubDate>
		<dc:creator>makka</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[nhibernate]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Query execution plan]]></category>
		<category><![CDATA[SQLServer]]></category>

		<guid isPermaLink="false">http://testdrivendevelopment.wordpress.com/2009/03/10/nhibernate-queries-sql-server-execution-plans/</guid>
		<description><![CDATA[In these days I’m working with Andrea on a web application using ASP.NET &#38; SQL Server . You should kwon that Andrea, is a SQL Server MVP, but fortunately is not a T-SQL taliban so he agree without hesitation when I proposed to use NHibernate to build our data access layer. When a tool can [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=testdrivendevelopment.wordpress.com&blog=2459763&post=80&subd=testdrivendevelopment&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In these days I’m working with <a href="http://community.ugiss.org/blogs/abenedetti">Andrea</a> on a web application using ASP.NET &amp; SQL Server . You should kwon that <a href="http://community.ugiss.org/blogs/abenedetti">Andrea</a>, is a SQL Server MVP, but fortunately is not a T-SQL taliban so he agree without hesitation when I proposed to use NHibernate to build our data access layer. When a tool can help us while building an application why not use it ?</p>
<p>As you can image a skilled DBA like <a href="http://community.ugiss.org/blogs/abenedetti">Andrea</a> can rapidly find a bottleneck in any query fired to a database. While writing a simple query using NHibernate API we noticed a strange behavior of NHibernate 2.0 with parameters. Here is the code we wrote:</p>
<pre style="width:697px;height:206px;"><span style="color:#0000ff;">using</span> (ISession session = factory.OpenSession())
{
	<span style="color:#008000;">//nvarchar(4)</span>
	session.CreateQuery(&quot;<span style="color:#8b0000;">from Region r where r.Description like :desc</span>&quot;)
		.SetString(&quot;<span style="color:#8b0000;">desc</span>&quot;, &quot;<span style="color:#8b0000;">zon%</span>&quot;)
		.List();

	<span style="color:#008000;">//nvarchar(5)</span>
	session.CreateQuery(&quot;<span style="color:#8b0000;">from Region r where r.Description like :desc</span>&quot;)
		.SetString(&quot;<span style="color:#8b0000;">desc</span>&quot;, &quot;<span style="color:#8b0000;">zone%</span>&quot;)
		.List();
}</pre>
<p>This code generates these two sql queries:</p>
<pre style="width:697px;height:167px;">

<a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=exec&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">exec</a> <a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=sp_executesql&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">sp_executesql</a> N'<span style="color:#8b0000;">select region0_.RegionId as RegionId0_, region0_.RegionDescription as RegionDe2_0_ </span><span style="color:#8b0000;">from Region region0_ where (region0_.RegionDescription like @p0 )</span>',N'<span style="color:#8b0000;">@p0 nvarchar(4)</span>',@p0=N'<span style="color:#8b0000;">zon%</span>'

<a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=exec&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">exec</a> <a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=sp_executesql&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">sp_executesql</a> N'<span style="color:#8b0000;">select region0_.RegionId as RegionId0_, region0_.RegionDescription as RegionDe2_0_ </span><span style="color:#8b0000;">from Region region0_ where (region0_.RegionDescription like @p0 )</span>',N'<span style="color:#8b0000;">@p0 nvarchar(5)</span>',@p0=N'<span style="color:#8b0000;">zone%</span>'
</pre>
<p>As you can see the parameter type is different in the two statements. This unfortunately cause SqlServer to generate two different exection plans. If you need the best performace you should avoid this behaviour. If you send to the database queries using the same parameter (type &amp; size) SqlServer use his internal cache. You have already pay for it so why not to use it ?</p>
<p>I had the pleasure to discuss with Fabio Maulo about this topic (you can read <a href="http://groups.google.it/group/nh-it/browse_thread/thread/2925264ff8aad4c2">here</a>. The conversation is in italian). At the end I found this solution:</p>
<p>I edited my hibernate.cfg.xml file adding this node to the xml</p>
<pre><span style="color:#0000ff;">&lt;</span><span style="color:#800000;">property</span> <span style="color:#ff0000;">name</span>=<span style="color:#0000ff;">&quot;prepare_sql&quot;</span><span style="color:#0000ff;">&gt;</span>true<span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">property</span><span style="color:#0000ff;">&gt;</span></pre>
<p>and then I wrote this code:</p>
<pre style="width:696px;height:223px;"><span style="color:#0000ff;">using</span> (ISession session = factory.OpenSession())
{

	<span style="color:#008000;">//nvarchar(10)</span>
	session.CreateQuery(&quot;<span style="color:#8b0000;">from Region r where r.Description like :desc</span>&quot;)
		.SetParameter(&quot;<span style="color:#8b0000;">desc</span>&quot;, &quot;<span style="color:#8b0000;">zoneh%</span>&quot;, TypeFactory.GetStringType(10))
		.List();

	<span style="color:#008000;">//nvarchar(10)</span>
	session.CreateQuery(&quot;<span style="color:#8b0000;">from Region r where r.Description like :desc</span>&quot;)
		.SetParameter(&quot;<span style="color:#8b0000;">desc</span>&quot;, &quot;<span style="color:#8b0000;">neh%</span>&quot;, TypeFactory.GetStringType(10))
		.List();
}</pre>
<p>Now with this code NHibernate generates these two sql queries:</p>
<pre style="width:697px;height:250px;"><a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=declare&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">declare</a> @p1 <a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=int&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">int</a>
<a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=set&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">set</a> @p1=1
<a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=exec&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">exec</a> <a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=sp_prepexec&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">sp_prepexec</a> @p1 <a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=output&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">output</a>,N'<span style="color:#8b0000;">@p0 nvarchar(10)</span>',N'<span style="color:#8b0000;">select region0_.RegionId as RegionId0_, region0_.RegionDescription as RegionDe2_0_ from Region region0_ where (region0_.RegionDescription like @p0 )</span>',@p0=N'<span style="color:#8b0000;">zoneh%</span>'
select @p1

<a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=declare&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">declare</a> @p1 <a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=int&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">int</a>
<a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=set&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">set</a> @p1=2
<a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=exec&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">exec</a> <a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=sp_prepexec&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">sp_prepexec</a> @p1 <a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=output&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">output</a>,N'<span style="color:#8b0000;">@p0 nvarchar(10)</span>',N'<span style="color:#8b0000;">select region0_.RegionId as RegionId0_, region0_.RegionDescription as RegionDe2_0_ from Region region0_ where (region0_.RegionDescription like @p0 )</span>',@p0=N'<span style="color:#8b0000;">neh%</span>'
select @p1</pre>
<p>This is better cause the parameters length is always the same. Now your database will thank you for this! But wait you can still do something better.<br />
  <br />If your database column type is a varchar and not nvarchar you can improve your code using a different SqlDbType. How ? Whit his code:</p>
<pre style="width:694px;height:179px;"><a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=using&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">using</a> (ISession <a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=session&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">session</a> = factory.OpenSession())
{
	<a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=session&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">session</a>.CreateQuery(&quot;<span style="color:#8b0000;">from Region r where r.Description like :desc</span>&quot;)
		.SetParameter(&quot;<span style="color:#8b0000;">desc</span>&quot;, &quot;<span style="color:#8b0000;">z%</span>&quot;, TypeFactory.GetAnsiStringType(15))
		.List();

	<a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=session&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">session</a>.CreateQuery(&quot;<span style="color:#8b0000;">from Region r where r.Description like :desc</span>&quot;)
		.SetParameter(&quot;<span style="color:#8b0000;">desc</span>&quot;, &quot;<span style="color:#8b0000;">za%</span>&quot;, TypeFactory.GetAnsiStringType(15))
		.List();
}</pre>
<p>Now the parameter type is a varchar and the size is always 15. Whit this latest improvement you remove a CONVER_IMPLICIT operation from your query execution plan (futher details <a href="http://community.ugiss.org/blogs/abenedetti/archive/2009/03/03/ancora-su-query-e-sulla-definizione-dei-parametri-perfomance-e-piani-di-esecuzione.aspx">here</a> but in italian ). This cast operation cost something so if you don’t need it why to remove it ? </p>
<p>I hope this will help someone (dev &amp; dba) in the future!</p>
<div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:955906c9-8de5-4d71-aba2-1031ea316d18" style="display:inline;float:none;margin:0;padding:0;">Technorati Tag: <a href="http://technorati.com/tags/NHibernate" rel="tag">NHibernate</a>,<a href="http://technorati.com/tags/SQLServer" rel="tag">SQLServer</a>,<a href="http://technorati.com/tags/Query+execution+plan" rel="tag">Query execution plan</a>,<a href="http://technorati.com/tags/ORM" rel="tag">ORM</a></div>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/testdrivendevelopment.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/testdrivendevelopment.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/testdrivendevelopment.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/testdrivendevelopment.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/testdrivendevelopment.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/testdrivendevelopment.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/testdrivendevelopment.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/testdrivendevelopment.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/testdrivendevelopment.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/testdrivendevelopment.wordpress.com/80/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=testdrivendevelopment.wordpress.com&blog=2459763&post=80&subd=testdrivendevelopment&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://testdrivendevelopment.wordpress.com/2009/03/10/nhibernate-queries-sql-server-execution-plans/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/eaac7e727c1e026a9677bf418eca3ee9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">makka</media:title>
		</media:content>
	</item>
	</channel>
</rss>