<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.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>Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx</link><description>In my previous post, I debugged a customer problem for you, including the various guesses I had to make and why they matter. 
 The specific problem was likely related to parameter sensitivity, an issue in query optimization where the optimizer will try</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx#10303723</link><pubDate>Thu, 10 May 2012 11:45:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10303723</guid><dc:creator>Gulli Meel</dc:creator><description>&lt;p&gt;One more thing you could do is that. Find the threshold value beyond which scan will be better and before this threshold seek + lookup is better. So if value is above threshold execute a query with forced scan plan using hints and below that use forced seek + lookup. I know it can not be done at optimizer level because optimizer wont be having these details stored somewhere.But an application designer or developer who knows what kind of data is there in table and how the data is accessed and how many times sql is called and what is the ratio of the values below threshold and above threshold. Thus based on this you could tweak the code to take adavntage of this technique to make all your queries as efficient as possible.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10303723" width="1" height="1"&gt;</description></item><item><title>re: Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx#10052518</link><pubDate>Fri, 20 Aug 2010 17:16:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10052518</guid><dc:creator>Conor</dc:creator><description>&lt;p&gt;caching is done with an exact string match today. (memcmp), broadly.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10052518" width="1" height="1"&gt;</description></item><item><title>re: Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx#10051165</link><pubDate>Tue, 17 Aug 2010 20:25:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10051165</guid><dc:creator>David W Wright</dc:creator><description>&lt;p&gt;Thanks Leon, that&amp;#39;s a useful script.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10051165" width="1" height="1"&gt;</description></item><item><title>re: Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx#10050634</link><pubDate>Mon, 16 Aug 2010 17:47:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10050634</guid><dc:creator>los</dc:creator><description>&lt;p&gt;Let me start by stating I am quite new to the world of SQL Server and DB administration in general. I&amp;#39;m trying to learn as much as I can.&lt;/p&gt;
&lt;p&gt;My understanding of parameterized queries and cached plans is that each subsequent query must be identical to the cached &amp;nbsp;version. My question is how identical must future queries be? Does it have to be identical character for character? Is the optimizer smart enough to recognize simple difference in column or predicate order? What if the only difference is the name of the database being queried?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10050634" width="1" height="1"&gt;</description></item><item><title>re: Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx#10050515</link><pubDate>Mon, 16 Aug 2010 13:45:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10050515</guid><dc:creator>Leon</dc:creator><description>&lt;p&gt;@David,&lt;/p&gt;
&lt;p&gt;I use this query to find the cached query plans. &amp;nbsp;It takes a while to run depending on how you write the where clause but it works most of the time. &amp;nbsp;When run against a production environment usually you can finger the highest volume plan as the one most used. &amp;nbsp;If you click on the xml output and it&amp;#39;s a suboptimal plan then you most likely have your winner. &amp;nbsp;Hope this helps.&lt;/p&gt;
&lt;p&gt;select * from sys.dm_exec_cached_plans c&lt;/p&gt;
&lt;p&gt;cross apply sys.dm_exec_query_plan(plan_handle) p&lt;/p&gt;
&lt;p&gt;cross apply sys.dm_exec_sql_text(plan_handle) s&lt;/p&gt;
&lt;p&gt;where s.[text] like &amp;#39;%query string here%&amp;#39; &lt;/p&gt;
&lt;p&gt;and usecounts &amp;gt; 50 &amp;nbsp;-- I set this around 50 to filter out tests run by developers. &amp;nbsp;For the most part I don&amp;#39;t care about the low volume plans, it&amp;#39;s usually the high volume ones that kill you, in prod at least.&lt;/p&gt;
&lt;p&gt;Leon&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10050515" width="1" height="1"&gt;</description></item><item><title>re: Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx#10050514</link><pubDate>Mon, 16 Aug 2010 13:44:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10050514</guid><dc:creator>David W Wright</dc:creator><description>&lt;p&gt;Interesting. &amp;nbsp;My problem wasn&amp;#39;t due to a parameter, so I didn&amp;#39;t use OPTIMISE FOR @p=whatever. &amp;nbsp;I added option(RECOMPILE) to the query (instead of for the whole proc), but it did not help, perhaps because it was recompiling against misleading stats from when [Selection_Date] was always NULL, (is that what you mean by a gatekeeper case?). &amp;nbsp;So I put UPDATE STATISTICS [tablename]; immediately before the query, and this + the recompile in the query DOES seem to have fixed the problem. &amp;nbsp;I haven&amp;#39;t been able to make it go wrong yet anyway!&lt;/p&gt;
&lt;p&gt;Thanks for your help and guidance. &amp;nbsp;I think I&amp;#39;ve fixed my problem, and I&amp;#39;ve learned a lot about SQL Server DMVs, statistics and execution plans in the process.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10050514" width="1" height="1"&gt;</description></item><item><title>re: Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx#10050344</link><pubDate>Mon, 16 Aug 2010 00:42:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10050344</guid><dc:creator>Conor Cunningham [MSFT]</dc:creator><description>&lt;p&gt;Please read my earlier blog post on batch compilation in SQL Server:&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://blogs.msdn.com/b/conor_cunningham_msft/archive/2009/06/03/conor-vs-dynamic-sql-vs-procedures-vs-plan-quality-for-parameterized-queries.aspx?wa=wsignin1.0"&gt;blogs.msdn.com/.../conor-vs-dynamic-sql-vs-procedures-vs-plan-quality-for-parameterized-queries.aspx&lt;/a&gt;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10050344" width="1" height="1"&gt;</description></item><item><title>re: Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx#10050302</link><pubDate>Sun, 15 Aug 2010 20:17:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10050302</guid><dc:creator>David W Wright</dc:creator><description>&lt;p&gt;Thanks. &amp;nbsp;The profiler didn&amp;#39;t help much - simply too much data - but &lt;/p&gt;
&lt;p&gt; SELECT * FROM sys.dm_exec_requests ORDER BY logical_reads DESC;&lt;/p&gt;
&lt;p&gt;gave me a clue - though sys.dm_exec_query_plan() showed a plan of NULL while running, and there was nothing in the cache afterwards due to WITH RECOMPILE. &amp;nbsp; However, I did manage to work out a situation in which the problem ALWAYS happens, so I could then run the query under test in SSMS on my development system and see the Actual Execution Plan when it finished - 7 hours later! &amp;nbsp;99% of time doing CLUSTERED INDEX SEEK on estimated 1 row, actual 9722 rows. &amp;nbsp;BUT the rest of the plan involved two Nested Loops (1%), one of which had met an Actual 2498 million rows instead of its Estimated 1 row!!!&lt;/p&gt;
&lt;p&gt;So I did EXEC sp_updatestats and ran the query again - this time it took just 4 seconds, with a completely different plan that used the secondary indexes on [Order_Number] and [Order_Date], and did Hash Matches. &amp;nbsp;This DESPITE the fact that there was an sp_updatestats just before the proc had run. &amp;nbsp;Which also gave me a clue; the query in question is near the end of the proc, and depends on fields [Order_Date] and [Selection_Date]. The latter is set by the previous UPDATE step. &amp;nbsp;If we&amp;#39;re loading new data, [Selection_Date] would have been all NULL at the start of the proc - so the plan created at that point would have assumed it still was; hence the pathologically bad plan. &amp;nbsp;Maybe I should put a WITH RECOMPILE in the query itself? &amp;nbsp;Or an UPDATE STATS for that index? Or add a hint to use the [Index_Date] index? &amp;nbsp;(This is all new to me; I always thought &amp;quot;SQL Server knows best&amp;quot; before!).&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10050302" width="1" height="1"&gt;</description></item><item><title>re: Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx#10050056</link><pubDate>Sat, 14 Aug 2010 00:16:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10050056</guid><dc:creator>Conor</dc:creator><description>&lt;p&gt;The main thing I can recommend is capturing the query plans (sql profiler, DMVs) when you see this case happening. &amp;nbsp;This would give you insight into what is happening - table scan, lots of random IOs, etc. &amp;nbsp;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10050056" width="1" height="1"&gt;</description></item><item><title>re: Conor vs. Misbehaving Parameterized Queries + OPTIMIZE FOR hints</title><link>http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx#10050039</link><pubDate>Fri, 13 Aug 2010 23:01:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10050039</guid><dc:creator>David W Wright</dc:creator><description>&lt;p&gt;And of course, soon after I posted that, the job once again took 100 minutes for a step that normally takes 2 seconds, DESPITE the WITH RECOMPILE&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10050039" width="1" height="1"&gt;</description></item></channel></rss>