<?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/"
	>

<channel>
	<title>Clay Lenhart's Blog &#187; execution plan</title>
	<atom:link href="http://clay.lenharts.net/blog/tag/execution-plan/feed/" rel="self" type="application/rss+xml" />
	<link>http://clay.lenharts.net/blog</link>
	<description>A blog on .Net and SQL Server</description>
	<lastBuildDate>Tue, 31 Oct 2017 10:34:08 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.2.2</generator>
	<item>
		<title>Execution Plan of Frequent Queries</title>
		<link>http://clay.lenharts.net/blog/2009/05/29/execution-plan-of-frequent-queries/</link>
		<comments>http://clay.lenharts.net/blog/2009/05/29/execution-plan-of-frequent-queries/#comments</comments>
		<pubDate>Fri, 29 May 2009 19:03:42 +0000</pubDate>
		<dc:creator><![CDATA[Clay Lenhart]]></dc:creator>
				<category><![CDATA[SQL Server Administration]]></category>
		<category><![CDATA[dynamic management views]]></category>
		<category><![CDATA[execution plan]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[SQL Server Engine]]></category>

		<guid isPermaLink="false">http://clay.lenharts.net/blog/?p=110</guid>
		<description><![CDATA[Bill Galashan, DBA of bet365 sent over the following query that lists the execution plan of the 10 most frequently executed queries. <a href="http://clay.lenharts.net/blog/2009/05/29/execution-plan-of-frequent-queries/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Bill Galashan, DBA of <a href="http://www.bet365.com/">bet365</a> sent over the following query that lists the execution plan of the 10 most frequently executed queries.</p>
<p>He writes:</p>
<blockquote><p>We got into this due to different query plans coming from a VB or a web app than what was seen when running the same query from Management Studio. Eventually tracked this down to a difference in the set options predominatley whether Arithabort was on or off. </p></blockquote>
<p>Read more to see his query.<span id="more-110"></span></p>
<p>Click here to <a href="http://clay.lenharts.net/blog/2008/04/13/cached-execution-plans-in-sql-server/">see the execution plan of currently running queries</a>. </p>
<pre class="brush: sql; title: ; notranslate">
SELECT TOP 10 creation_time, last_execution_time,  last_worker_time / 1000 as [Last Worker Time (ms)] ,min_worker_time / 1000 as [Min Worker Time (ms)], 
      max_worker_time / 1000 as [Max Worker Time (ms)],
    total_worker_time/execution_count/1000 AS [Avg Worker Time (ms)],
    execution_count, 
    SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,
    ((CASE statement_end_offset 
        WHEN -1 THEN DATALENGTH(st.text)
        ELSE qs.statement_end_offset 
        END 
            - qs.statement_start_offset)/2) + 1) as statement_text,plan_generation_num ,query_plan, Plan_handle
FROM sys.dm_exec_query_stats as qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as st
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle)
-- where st.text like '%proc name to be searched for%'
ORDER BY execution_count DESC;
</pre>
<pre class="brush: sql; title: ; notranslate">
--- Determine options used at run time

select  * from sys.syscacheobjects with (nolock) where sql like '%proc to be searched for%' and objtype='proc'


select dbo.fn_setopts(249)

/*
 This contains a bitmap containing the SET options relevant to each cached plan for a proc.
The following function can be used to decipher this bitmask:
*/

 

create function dbo.fn_setopts(@setopts int)
returns nvarchar(4000)

as
begin

declare @s nvarchar(4000)
select @s='Options: '
if @setopts &amp;amp;amp;amp;amp; 1    &gt; 0 select @s = @s + N'ANSI_PADDING, ' 
if @setopts &amp;amp;amp;amp;amp; 2    &gt; 0 select @s = @s + N'max degree of parallelism, '
if @setopts &amp;amp;amp;amp;amp; 4    &gt; 0 select @s = @s + N'FORCEPLAN, ' 
if @setopts &amp;amp;amp;amp;amp; 8    &gt; 0 select @s = @s + N'CONCAT_NULL_YIELDS_NULL, '
if @setopts &amp;amp;amp;amp;amp; 16   &gt; 0 select @s = @s + N'ANSI_WARNINGS, '
if @setopts &amp;amp;amp;amp;amp; 32   &gt; 0 select @s = @s + N'ANSI_NULLS, '
if @setopts &amp;amp;amp;amp;amp; 64   &gt; 0 select @s = @s + N'QUOTED_IDENTIFIER, '
if @setopts &amp;amp;amp;amp;amp; 128  &gt; 0 select @s = @s + N'ANSI_NULL_DFLT_ON, '
if @setopts &amp;amp;amp;amp;amp; 256  &gt; 0 select @s = @s + N'ANSI_NULL_DFLT_OFF, '
if @setopts &amp;amp;amp;amp;amp; 512  &gt; 0 select @s = @s + N'NO_BROWSETABLE, '
if @setopts &amp;amp;amp;amp;amp; 1024 &gt; 0 select @s = @s + N'TriggerOneRow, '
if @setopts &amp;amp;amp;amp;amp; 2048 &gt; 0 select @s = @s + N'ResyncQuery, '
if @setopts &amp;amp;amp;amp;amp; 4096 &gt; 0 select @s = @s + N'ARITHABORT, '
if @setopts &amp;amp;amp;amp;amp; 8192 &gt; 0 select @s = @s + N'NUMERIC_ROUNDABORT, ' 

return @s

end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://clay.lenharts.net/blog/2009/05/29/execution-plan-of-frequent-queries/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Influencing the Execution Plan</title>
		<link>http://clay.lenharts.net/blog/2008/04/14/influencing-the-execution-plan/</link>
		<comments>http://clay.lenharts.net/blog/2008/04/14/influencing-the-execution-plan/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 20:37:56 +0000</pubDate>
		<dc:creator><![CDATA[Clay Lenhart]]></dc:creator>
				<category><![CDATA[SQL Server Development]]></category>
		<category><![CDATA[execution plan]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[SQL Server Engine]]></category>

		<guid isPermaLink="false">http://clay.lenharts.net/blog/?p=36</guid>
		<description><![CDATA[I had a performance problem recently with SQL Server. This post shows an easy relatively hands-off approach to influencing the execution plan. <a href="http://clay.lenharts.net/blog/2008/04/14/influencing-the-execution-plan/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I had a performance problem recently with SQL Server, and I went through the standard <a href="http://www.sql-server-performance.com/articles/per/performance_audit_part6_p1.aspx">performance checklist</a>, however it didn&#8217;t solve the problem permanently.  Sometimes it would perform well, but most times it was performing poorly.  I knew the next step was to mess with the execution plan.  This is something I really don&#8217;t like.<span id="more-36"></span></p>
<p>You do not want to force SQL Server to use a particular execution plan, because SQL Server can pick different execution plans depending on how much data will be processed.  When it processes a few rows, it will choose a plan that is optimized for a few rows (and typically use nested loops).  If the same script processes a lot of rows, it will use a plan that is optimized for a lot of rows (and use merge joins or hash joins).  By forcing SQL Server to use single execution plan, you prevent it from using the most efficient execution plan for different scenarios.</p>
<p>But what happens if SQL Server estimates the wrong number of rows?  The worst thing it can do is estimate few rows, use an execution plan optimized for a few rows, and actually process a large number of rows.  In this scenario, you will find a very slow query.</p>
<p>I found an easy fix for this situation.  Use the <a href="http://msdn2.microsoft.com/en-us/library/ms181714.aspx">OPTION</a>(HASH JOIN, MERGE JOIN) modifier to any SELECT, INSERT, UPDATE, or DELETE statement.  For instance:</p>
<pre class="brush: sql; title: ; notranslate">UPDATE cust
SET CustomerSourceID = th.SourceID
FROM Customer cust
INNER JOIN TransactionHeader th ON th.CustomerID = cust.CustomerID
WHERE cust.CustomerSourceID IS NULL
OPTION (HASH JOIN, MERGE JOIN)</pre>
<p>The OPTION (HASH JOIN, MERGE JOIN) modifier does not allow SQL Server to use nested loops.  Since nested loops are typically efficient for a small number of rows, this causes SQL Server to optimize your query for a large number of rows.  Even if this query encounters a few rows, the plan will be moderately efficient.</p>
<p>The good thing about OPTION (HASH JOIN, MERGE JOIN) is</p>
<ul>
<li>It does not require a statement to be restructured.</li>
<li>It will not likely introduce any bugs.</li>
</ul>
<p>The bad thing about it is</p>
<ul>
<li>You prevent SQL Server from selecting the best execution plan for all scenarios.  The plan will be optimized for a large number of rows.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://clay.lenharts.net/blog/2008/04/14/influencing-the-execution-plan/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Cached Execution Plans in SQL Server</title>
		<link>http://clay.lenharts.net/blog/2008/04/13/cached-execution-plans-in-sql-server/</link>
		<comments>http://clay.lenharts.net/blog/2008/04/13/cached-execution-plans-in-sql-server/#comments</comments>
		<pubDate>Sun, 13 Apr 2008 20:38:04 +0000</pubDate>
		<dc:creator><![CDATA[Clay Lenhart]]></dc:creator>
				<category><![CDATA[SQL Server Administration]]></category>
		<category><![CDATA[dynamic management views]]></category>
		<category><![CDATA[execution plan]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[SQL Server Engine]]></category>

		<guid isPermaLink="false">http://clay.lenharts.net/blog/?p=35</guid>
		<description><![CDATA[This blog entry describes how you can get the SQL Server execution plan of any running statement and display the graphical representation in Enterprise Manager. <a href="http://clay.lenharts.net/blog/2008/04/13/cached-execution-plans-in-sql-server/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><em>I have been working on a performance problem recently, so you might see several blog entries with information that help me.  Hopefully they will help you.</em></p>
<p>Update: Here is a query to get the <a href="http://clay.lenharts.net/blog/2009/05/29/execution-plan-of-frequent-queries/">execution plan of the most frequently used queries</a>.</p>
<p>Getting the SQL Server execution plan from a production can be difficult, since you are not running the code within Enterprise Manager.  You can still get the execution plan of any running statement and display the graphical representation in Enterprise Manager.<span id="more-35"></span></p>
<p>If your script is currently running, you can <a href="http://blogs.technet.com/vipulshah/archive/2007/09/24/notes-taken-during-pass-session-plan-cache-analysis-in-sql-server-2005.aspx">lookup its execution plan</a> in the plan cache.  The steps are:</p>
<ol>
<li>Run a query to get the the plan_handle of currently running code</li>
<li>Lookup the execution plan for the plan_handle.</li>
</ol>
<p>The first query is:</p>
<pre class="brush: sql; title: ; notranslate">SELECT
sder.session_id AS [SPID],
sder.sql_handle as [SQL_Handle],
sder.plan_handle as [PLAN_Handle],
sdes.login_name AS [Login],
sd.name AS [DBName],
sder.start_time AS [Start Time],
sder.status AS [Status],
sder.command AS [Command],
sdet.text AS [SQL Text],
sder.percent_complete AS [Pct Cmplt],
sder.estimated_completion_time AS [Est Cmplt Time],
sder.wait_type AS [Wait],
sder.wait_time AS [Wait Time],
sder.last_wait_type AS [Last Wait],
sder.cpu_time AS [CPU Time],
sder.total_elapsed_time AS [Total Elpsd Time],
sder.reads AS [Reads],
sder.writes AS [Writes],
sder.logical_reads AS [Logical Reads]
FROM
sys.dm_exec_Requests sder
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sdet
JOIN sys.dm_exec_sessions sdes on sder.session_id = sdes.session_id
JOIN sys.databases sd on sder.database_id = sd.database_id
WHERE
sder.session_id &lt;&gt; @@SPID and sder.session_id &gt; 50</pre>
<p>The second query is:</p>
<pre class="brush: sql; title: ; notranslate">SELECT * FROM sys.dm_exec_query_plan ( &lt;PLAN_Handle&gt; )
--here &lt;PLAN_Handle&gt; is supplied based on
--the results from the first query.</pre>
<p>This gives you the XML execution plan that you can copy and paste into notepad, save it with a *.sqlplan extension, and double click on the file to view the graphical version of the execution plan.</p>
]]></content:encoded>
			<wfw:commentRss>http://clay.lenharts.net/blog/2008/04/13/cached-execution-plans-in-sql-server/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
	</channel>
</rss>
