<?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>Microsoft Dynamics NAV Sustained Engineering Team Blog : 2005 performance</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx</link><description>Tags: 2005 performance</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Cursor Types</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2009/02/20/cursor-types.aspx</link><pubDate>Fri, 20 Feb 2009 11:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9435660</guid><dc:creator>Lohndorf</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/9435660.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=9435660</wfw:commentRss><description>&lt;P&gt;One of the changes in Microsoft Dynamics NAV version 5, was to change from primarily making use of Fast-Forward cursor types to Dynamic cursors. The same change was implemented in version 4 from build 26410, which is Version 4, SP3 Update6(940718) + KB950920.&lt;/P&gt;
&lt;P&gt;The change of cursor type can also mean a change in behaviour.&amp;nbsp;With Dynamic cursors, SQL Server more often optimises for the ORDER BY - part of a SQL query than is the case with Fast Forward cursors. This is because a result set based on a dynamic&amp;nbsp;cursor has to include new rows. IF SQL Server were to choose an index that fits the WHERE clause then it would have to sort all rows according to the ORDER BY before returning the first row to the client and that by definition is a STATIC result-set. &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Take this query as an example:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;SELECT&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;*&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; "Demo Database NAV (6-0)"&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;"dbo"&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;"CRONUS International Ltd_$Item Ledger Entry" &lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;WITH&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;READUNCOMMITTED&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;undefined&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;((&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;"Document No_"&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;&lt;A href="mailto:=@P1"&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;ORDER&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;BY&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; "Item No_"&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;"Posting Date"&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;"Entry No_"&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;BR&gt;With Fast-Forward cursors, in this example SQL Server is likely to try to optimise for the WHERE clause, which is "Document No.". But with&amp;nbsp;the ORDER BY clause specifying a different sorting, SQL Server may then&amp;nbsp;chose a clustered index scan instead.&lt;/P&gt;
&lt;P&gt;With Dynamic cursors, SQL Server is more likely to optimise for the ORDER BY clause, which is a valid and existing index. So in this exampe SQL server&amp;nbsp;would chose an index scan on this index. You can see this by running the query from SQL Server Management Studio like this:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p1 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p1&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=-&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;1&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;--declare @p3 int set @p3=16+4096+8192 -- Fast Forward &lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p3 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p3&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;2&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;4096&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;8192 &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;&lt;FONT color=#008000 size=2&gt;-- Dynamic &lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p4 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p4&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;1&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p5 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p5&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;49&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;--declare @p5 int set @p5=15 – FAST 15&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;exec&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; sp_cursoropen @p1 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;N&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'&lt;/P&gt;
&lt;P&gt;SELECT * FROM "Demo Database NAV (6-0)"."dbo"."CRONUS International Ltd_$Item Ledger Entry" &lt;/P&gt;
&lt;P&gt;WITH (READUNCOMMITTED) &lt;/P&gt;
&lt;P&gt;WHERE (("Document No_"=@P1)) &lt;/P&gt;
&lt;P&gt;ORDER BY "Item No_","Posting Date","Entry No_"&lt;/P&gt;
&lt;P&gt;'&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;
&lt;P&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;@p3&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;output&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;@p4 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;@p5 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;N&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'@P1 varchar(20)'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;
&lt;P&gt;'START'&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;select&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p1&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p3&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p4&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; @p5&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;exec&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; sp_cursorclose @p1&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;You can enable / disable the 2nd and 3rd line to switch between Fast-Forward or Dynamic cursor, and see the result in the query plan that gets generated.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How does this affect NAV?&lt;/STRONG&gt;&lt;BR&gt;The change in behaviour can mean that certain queries that ran without problems may be slow, after a customer upgrades the platform to the builds mentioned above. In cases &lt;/P&gt;
&lt;P&gt;that we have seen, the problem has been limited to one or very few specific queries, typically on filtered forms, that were slow after upgrading the platform. Use the query from here:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;A class="" href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/10/14/simple-query-to-check-the-recent-performance-history-ii-now-including-query-plan-information.aspx" target=_blank mce_href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/10/14/simple-query-to-check-the-recent-performance-history-ii-now-including-query-plan-information.aspx"&gt;Simple query to check the recent performance history II - now including Query Plan information&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;to help identifying which queries to trouleshoot. Note that the query shows the Cursor Type in the rightmost column. Then look at whether SQL Server has an index to match the ORDER BY clause.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Also, be extra careful using the SQLIndex-property on keys. By setting this property, the ORDER BY-clause may not match a SQL index anymore, and a Dynamic cursor will have &lt;/P&gt;
&lt;P&gt;to scan the table.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Why this change?&lt;/STRONG&gt;&lt;BR&gt;Internal performance tests show that overall, Dynamic cursors give better performance and fewer blocks. So while the change may cause unforeseen changes in behaviour when a customer upgrades, overall we have seen better performance with Dynamic cursors.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P mce_keep="true"&gt;Escalation Engineer&lt;/P&gt;
&lt;P&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9435660" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>Simple query to check the recent performance history II - now including Query Plan information</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/10/14/simple-query-to-check-the-recent-performance-history-ii-now-including-query-plan-information.aspx</link><pubDate>Tue, 14 Oct 2008 12:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8999249</guid><dc:creator>Lohndorf</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8999249.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8999249</wfw:commentRss><description>&lt;P&gt;One of the queries I use the most, is the pplan-cache query from this post:&lt;/P&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/01/04/simple-query-to-check-the-recent-performance-history.aspx" target=_blank mce_href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/01/04/simple-query-to-check-the-recent-performance-history.aspx"&gt;Simple query to check the recent performance history&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The good thing about the query is that it shows information that could otherwise require a lot of work (collecting and analysing traces files). And the query does not need any advance work or setup.&amp;nbsp;It can just be run. So it's a very easy way to receive information from a system, which is often very useful as a first step in troubleshooting performance.&amp;nbsp;For more details about the result of the query, refer to the&amp;nbsp;post linked above.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Below is a slightly enhanced version of the query. Since the query is based on the cache of compiled query plans, it is not a big step to extend it to also include the query plan itself, and even extract certain information from the plan if you know what you are looking for.&lt;/P&gt;
&lt;P&gt;So this query does the same as the original one, but with the following additions:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;New column query_plan is included. It shows the query plan as xml which may be difficult to read, but it contains the full plan. Note: Some times, for no apparent reason, the query plan can't be retrieved, so it may not show the query plan on all lines.&lt;/LI&gt;
&lt;LI&gt;cursor_type, just as an example of how to retrieve data from the query plan. If you find other things in the plans that may be interesting, then use the syntax to retrieve this further information.&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here is the updated query&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;SELECT&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;TOP&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 100 &lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;&lt;FONT color=#ff00ff size=2&gt;SUBSTRING&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;st&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;text&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;qs&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;statement_start_offset&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;/&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;2&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 1&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;((&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; statement_end_offset &lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;-&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;1 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;&lt;FONT color=#ff00ff size=2&gt;DATALENGTH&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;st&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;text&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;ELSE&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; qs&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;statement_end_offset &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;-&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; qs&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;statement_start_offset&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)/&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;2&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 1&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; statement_text&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;execution_count&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;case&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;when&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; execution_count &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 0 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;then&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;null&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;else&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; total_logical_reads&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;/&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;execution_count &lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;end&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; avg_logical_reads&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;
&lt;P&gt;last_logical_reads&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;min_logical_reads&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;max_logical_reads&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;plan_handle&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;ph&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;query_plan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#008000 size=2&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;-- Query Plan Information&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;case&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;when&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;
&lt;P&gt;ph&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;query_plan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;exist&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtCursor/ns:CursorPlan/@CursorRequestedType)[1]'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 0&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;then&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;else&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;ph&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;query_plan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;value&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtCursor/ns:CursorPlan/@CursorRequestedType)[1]'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'nvarchar (max)'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;end&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; cursor_type&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;FROM&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;&lt;FONT color=#008000 size=2&gt;sys.dm_exec_query_stats&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; qs&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;
&lt;P&gt;CROSS&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;APPLY&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; sys.dm_exec_sql_text&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;qs&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;sql_handle&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; st &lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;
&lt;P&gt;CROSS&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;APPLY&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; sys.dm_exec_query_plan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;qs&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;plan_handle&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; ph&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;ORDER&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;BY&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; max_logical_reads &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;DESC&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;What I would really like, is to receive feedback on what parts of the query plans are useful. Then extend the query even further to include as much useful information as possible.&amp;nbsp;For exdample, in some cases the query plan contains missing index-information. The lines below can be copied into the query above to include this information. Any feedback on whether this is useful or not, and whether other information from the query plans can be useful is really very welcome. You can add comments about this below.&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#008000 size=2&gt;&lt;FONT color=#008000 size=2&gt;&amp;nbsp;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;&lt;FONT color=#008000 size=2&gt;-- Missing Indexes&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;
&lt;P&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;case&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;when&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; ph&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;query_plan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;exist&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:MissingIndexes/ns:MissingIndexGroup)[1]'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 0&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;then&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;else&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; ph&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;query_plan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;value&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:MissingIndexes/ns:MissingIndexGroup/@Impact)[1]'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'nvarchar (max)'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;end&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; missing_index_impact&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;case&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;when&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; ph&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;query_plan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;exist&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:MissingIndexes/ns:MissingIndexGroup/ns:MissingIndex/@Table)[1]'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 0&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;then&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;else&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; ph&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;query_plan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;value&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:MissingIndexes/ns:MissingIndexGroup/ns:MissingIndex/@Table)[1]'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'nvarchar(max)'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;end&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; missing_index_table&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;case&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;when&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; ph&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;query_plan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;exist&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:MissingIndexes/ns:MissingIndexGroup/ns:MissingIndex/ns:ColumnGroup/ns:Column/@Name)[1]'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 0&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;then&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;else&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; ph&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;query_plan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;value&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:MissingIndexes/ns:MissingIndexGroup/ns:MissingIndex/ns:ColumnGroup/ns:Column/@Name)[1]'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#ff0000 size=2&gt;'nvarchar(max)'&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;end&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; missing_index_field&lt;/P&gt;&lt;/FONT&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P mce_keep="true"&gt;Escalation Engineer&lt;/P&gt;
&lt;P&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8999249" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>Session Monitor for SQL Server 2005</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/09/11/session-monitor-for-sql-server-2005.aspx</link><pubDate>Thu, 11 Sep 2008 18:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8944736</guid><dc:creator>Lohndorf</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8944736.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8944736</wfw:commentRss><description>&lt;P&gt;Session Monitor is not a new tool, but it did stop working with SQL Server 2005. So I think that a lot of people stopped using it, which is a shame. The things that were broken now work again, and I would recommend anyone with any kind of blocking problems to implement this tool. With this post I hope to get some people to use it again, and to provide a new tool to anyone who did not know it exists.&lt;/P&gt;
&lt;H2&gt;Purpose of the tool&lt;/H2&gt;
&lt;P&gt;The purpose of the Session Monitor tool is to show a live picture of any current blocks in the Microsoft Dynamics NAV database. And to show it in a familiar environment, i.e. a NAV form. It is an extension of the information you get when going to File -&amp;gt; Database -&amp;gt; Information, and drill down on Sessions.&lt;/P&gt;
&lt;H2&gt;What the tool does:&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;Shows live information about who is blocked by whom&lt;/LI&gt;
&lt;LI&gt;Shows which user is at the top of a blocking chain&lt;/LI&gt;
&lt;LI&gt;Shows if a user is involved in blocking, i.e. either being blocked or is blocking someone. So you can filter out all sessions that are not involved in blocking&lt;/LI&gt;
&lt;LI&gt;Shows the wait resource, i.e. on which table the block is&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This is how the Session Monitor shows a blocking situation:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/microsoft_dynamics_nav_sustained_engineering/WindowsLiveWriter/SessionMonitorforSQLServer2005_E2BC/SessionMonitor_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/microsoft_dynamics_nav_sustained_engineering/WindowsLiveWriter/SessionMonitorforSQLServer2005_E2BC/SessionMonitor_2.jpg"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=406 alt=SessionMonitor src="http://blogs.msdn.com/blogfiles/microsoft_dynamics_nav_sustained_engineering/WindowsLiveWriter/SessionMonitorforSQLServer2005_E2BC/SessionMonitor_thumb.jpg" width=756 border=0 mce_src="http://blogs.msdn.com/blogfiles/microsoft_dynamics_nav_sustained_engineering/WindowsLiveWriter/SessionMonitorforSQLServer2005_E2BC/SessionMonitor_thumb.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;As default it refreshes every second.&lt;/P&gt;
&lt;P&gt;Some of the useful features of Session Monitor are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Filter on "Involved in Blocking". Then, as soon as there is a block it will show up. This is especially useful when you have more sessions that can fit on the screen, which means that there might otherwise be a block outside of the form.&lt;/LI&gt;
&lt;LI&gt;Wait Resource tells you on which table the block is, which helps you get some idea about in which area of the application it is.&lt;/LI&gt;
&lt;LI&gt;Originating blocker ID shows the head-blocker. This is useful when a user is blocked by someone who is blocked by someone else, etc. &lt;/LI&gt;
&lt;LI&gt;Wait Time shows how long the block has been there.&lt;/LI&gt;&lt;/UL&gt;
&lt;H2&gt;How to get it to work&lt;/H2&gt;
&lt;P&gt;As mentioned, the tool stopped working in SQL Server 2005. But there are corrections for this now. First, download the tool, which is part of the "Performance Troubleshooting Guide", available for download here (PartnerSource login required):&lt;/P&gt;
&lt;P&gt;&lt;A href="https://mbs.microsoft.com/partnersource/products/navision/documentation/benchmarks/navisionsqlresourcekit.htm?printpage=false" target=_blank mce_href="https://mbs.microsoft.com/partnersource/products/navision/documentation/benchmarks/navisionsqlresourcekit.htm?printpage=false"&gt;Microsoft Navision SQL Resource Kit&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The original tool contains a SQL query (Session Monitor (SQL Server).sql) which is the part that doesn't work for SQL Server 2005. So don't run this query.&amp;nbsp; Run the query from this KB article instead (PartnerSource login required here too):&lt;/P&gt;
&lt;H3&gt;&lt;A href="https://mbs.microsoft.com/knowledgebase/KBDisplay.aspx?WTNTZSMNWUKNTMMYLSVQUSPTNTNSMQPYLWVKVPNNSOMLNKYXSOONZRWVUTPWQPVL" target=_blank mce_href="https://mbs.microsoft.com/knowledgebase/KBDisplay.aspx?WTNTZSMNWUKNTMMYLSVQUSPTNTNSMQPYLWVKVPNNSOMLNKYXSOONZRWVUTPWQPVL"&gt;KB 933042 - Error message when you use the Session Monitor feature in Microsoft Dynamics NAV: "Invalid length parameter passed to the substring function"&lt;/A&gt;&lt;/H3&gt;
&lt;P&gt;Note!: Run the query on the NAV database - not on Master, or any other database you have on SQL Server.&lt;/P&gt;
&lt;P&gt;In NAV, import the object "Session Monitor (SQL Server).fob" from the Performance Troubleshooting guide.&lt;/P&gt;
&lt;P&gt;Make one change - otherwise in some cases it will fail with an INSERT error:&lt;/P&gt;
&lt;P&gt;Design codeunit 150011 "Session Monitor Mgt. (SQL Srv)", and replace this line:&lt;/P&gt;
&lt;P&gt;RefreshUserActivity() &lt;BR&gt;SELECTLATESTVERSION; &lt;BR&gt;IF Session.FIND('-') THEN &lt;BR&gt;&amp;nbsp; REPEAT &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SessionTmp := Session; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // SessionTmp.INSERT; Remove this line and replace with:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF SessionTmp.INSERT THEN ; // New line&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp; UNTIL Session.NEXT = 0;&lt;/P&gt;
&lt;P&gt;Those are the changes needed to get it to run on SQL Server 2005,&lt;/P&gt;
&lt;P&gt;Lars Lohndorf-Larsen &lt;/P&gt;
&lt;P&gt;Escalation Engineer &lt;/P&gt;
&lt;P&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8944736" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>Modern NAV/SQL troubleshooting II</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/06/11/modern-nav-sql-troubleshooting-ii.aspx</link><pubDate>Wed, 11 Jun 2008 18:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8591516</guid><dc:creator>Lohndorf</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8591516.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8591516</wfw:commentRss><description>&lt;P&gt;Please refer to &lt;A class="" href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/05/12/modern-nav-sql-troubleshooting.aspx" target=_blank mce_href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/05/12/modern-nav-sql-troubleshooting.aspx"&gt;this post&lt;/A&gt; about what I mean with "modern troubleshooting". &lt;/P&gt;
&lt;P&gt;This post describes methods that work on any version of SQL Server, including SQL2000. It describes one of the most common questions I get, which is "Where do we start"...&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;STRONG&gt;General performance problems - where to start:&lt;/STRONG&gt;&lt;BR&gt;If a system is suffering general performance problems, then it is not always easy to decide what to do first, or where to start. Then you may be tempted to collect lots of information, for example Profiler traces and databases which may or may not give any results, but which is guaranteed to require a lot of work both to collect, to send, and to analyse.&lt;/P&gt;
&lt;P&gt;Often, over-indexing&amp;nbsp;is one of the main causes of both bad performance problems and blocking. Indexes take time to maintain, and updating an index causes locks, which in turn can contribute to blocking-problems. so in a cases where the problem can't be located to a specific action, one place to start is to do some index tuning.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;In a case like that, I often begin by asking for just two files:&lt;BR&gt;Excel spreadsheet containing Table Information&lt;BR&gt;A&amp;nbsp;NAV backup or fob file which contains the customer's objects, but not their data&lt;/P&gt;
&lt;P&gt;Each of these files don't take long to prepare, and are normally small enough to send by email.&lt;/P&gt;
&lt;P&gt;You collect the Excel spreadsheet like this:&lt;BR&gt;In NAV, go to File -&amp;gt; Database -&amp;gt; Information, and click on Tables.&lt;BR&gt;Copy this into an Excel spreadhseet.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;When you get the spreadsheet, sort it by "No. of Records", or by "Size (KB)". The difference is, that "Size (KB)" includes the size of the indexes on each table. So either way of sorting gives you a good idea of which tables are being updated the most, and which tables have lots of both records and indexes.&lt;/P&gt;
&lt;P&gt;Then load the NAV objects that you also received, and for the top 5 - 10 tob tables in the spreadsheet, take a look at the tables in NAV, and check the number of keys and SIFT-indexes. Some times you will immediately see that these tables have had a lot of keys added, and you should try to see if you can reduce the number of keys, using the key properties MaintainSQLIndex, MaintainSIFTIndex and SIFTLevelsToMaintain (remember the SIFTLevelsToMaintain-property don't exist any longer in NAV 5 SP1 where it was removed as part of re-designing the SIFT system).&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;STRONG&gt;Which indexes to disable the SQL-maintenance of:&lt;/STRONG&gt;&lt;BR&gt;Only if you know how the system is being used, can you tell whether a certain index is being used or not. But, for example, a key like "IC Partner Code" in table 17 is only ever useful if the customer is using Intercompany Posting, and the "Additional-Currency Amount"-sumindex field on the same table is only needed if Additional currency is being used. So some times, a few obvious changes can be done. But to really do some index tuning, you need to know more than the objects alone can tell you.&lt;/P&gt;
&lt;P&gt;You can also take the opposite approach, and disable maintenance of all indexes and SIFT (except for the clustered index). This will show you which ones are really needed when certain processes begin to run very slowly, and you will then have to (quickly) re-enable those. This is of course a risky approach, but it can be quicker than analyzing each individual key.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In deciding which indexes may be disabled, the following tools may help as well:&lt;BR&gt;If running on SQL Server 2005 or later, run the query "Index Usage" (&lt;A class="" href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/02/26/index-usage-query.aspx" target=_blank mce_href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/02/26/index-usage-query.aspx"&gt;follow this link&lt;/A&gt;)&lt;/P&gt;
&lt;P&gt;The Key Information tool on the SQL Server Resource kit can help you deciding the cost of indexes per table, and help deciding the usefulness of SIFT indexes.&lt;BR&gt;With Navision Developers Tool (NDT), you can run "Where Used" on a key, to see in which object it is being used. If you use this method, then make sure to select everything in the "Where Used"-options. And keep in mind, that even with everyhthing selected, the NDT cannot see if users are manually specifying certain keys on the forms and reports they are running.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P&gt;Escalation Engineer&lt;/P&gt;
&lt;P&gt;These postings&amp;nbsp;are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8591516" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>Microsoft Dynamics NAV 5.0 SP1 and SQL Server 2000</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/06/03/microsoft-dynamics-nav-5-0-sp1-and-sql-server-2000.aspx</link><pubDate>Tue, 03 Jun 2008 14:22:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8571378</guid><dc:creator>Lohndorf</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8571378.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8571378</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;FONT face=Calibri size=3&gt;Microsoft Dynamics NAV 5.0 SP1 introduces a new way to handle SIFT. Instead of maintaining totals in separate tables, Dynamics NAV 5.0 SP1 uses a SQL feature called indexed views. Indexed views will automatically be maintained by the SQL Server.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;FONT face=Calibri size=3&gt;With SQL Server 2000, updating an indexed view can be a time consuming process as the SQL Server 2000 might decide to include a clustered index scan as part of its query plan to update the view. If your Microsoft Dynamics NAV implementation includes tables with many records and is based on Microsoft SQL Server 2000 there is a potential risk for experiencing bad performance.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;FONT face=Calibri size=3&gt;Microsoft Dynamics NAV 5.0 SP1 is optimized for Microsoft SQL Server 2005 and you should consider to upgrade to SQL Server 2005 if you are implementing Microsoft Dynamics NAV 5.0 SP1.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;FONT face=Calibri size=3&gt;The problem described here, only applies to SQL Server 2000. SQL Server 2005 handles the updates of indexed views much more efficiently.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P&gt;Escalation Engineer&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8571378" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>Changes to Microsoft Dynamics NAV 5.0 SP1 with Microsoft SQL Server</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/05/13/changes-to-microsoft-dynamics-nav-5-0-sp1-with-microsoft-sql-server.aspx</link><pubDate>Tue, 13 May 2008 11:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8499464</guid><dc:creator>martinni</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8499464.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8499464</wfw:commentRss><description>&lt;P&gt;I just want to point you to the whitepaper describing the changes done for the Microsoft Dynamics NAV 5.0 SP1 SQL Option:&lt;/P&gt;
&lt;P&gt;&lt;SPAN id=Body title=Body&gt;With the release of Microsoft Dynamics NAV™ 5.0 SP1, major changes have been made to Microsoft Dynamics NAV™ with Microsoft SQL Server. &lt;A class="" title=Whitepaper href="https://mbs.microsoft.com/partnersource/deployment/documentation/whitepapers/MD_NAV50_SP1_SQLServer" target=_blank mce_href="https://mbs.microsoft.com/partnersource/deployment/documentation/whitepapers/MD_NAV50_SP1_SQLServer"&gt;This document&lt;/A&gt; outlines these changes and shows how these changes can help you improve the Microsoft Dynamics NAV customer experience. &lt;A class="" title="White paper" href="https://mbs.microsoft.com/partnersource/deployment/documentation/whitepapers/MD_NAV50_SP1_SQLServer" mce_href="https://mbs.microsoft.com/partnersource/deployment/documentation/whitepapers/MD_NAV50_SP1_SQLServer"&gt;This document&lt;/A&gt; will only cover changes to Microsoft Dynamics NAV with SQL Server.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN title=Body&gt;Martin Nielander&lt;BR&gt;Program Manager&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN title=Body&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8499464" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/Release+Overview/default.aspx">Release Overview</category><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>Modern NAV/SQL troubleshooting</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/05/12/modern-nav-sql-troubleshooting.aspx</link><pubDate>Mon, 12 May 2008 13:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8493202</guid><dc:creator>Lohndorf</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8493202.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8493202</wfw:commentRss><description>&lt;P&gt;This post is the first in a planned series to describe various "modern" methods for troubleshooting performance problems with Microsoft Dynamics NAV on SQL Server. The idea is also to make the best out of information that already exists, either in other places on this blog or anywhere else.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;STRONG&gt;Modern Troubleshooting:&lt;/STRONG&gt;&lt;BR&gt;The idea about "Modern Troubleshooting" is:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;To take as much of the hard work out of troubleshooting as possible.&lt;/LI&gt;
&lt;LI&gt;To make the system itself (SQL Server and NAV) help you finding out what is wrong with it.&lt;/LI&gt;
&lt;LI&gt;To collect as little and as specific data as possible, to avoid having to read through for example gigabytes of trace files.&lt;/LI&gt;
&lt;LI&gt;To do the troubleshooting remotely as much as possible, rather than spending days on an individual system on site.&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;I want to make it clear that with "Troubleshooting", I mean "Trouble". And the methods I describe here will be quick-fixes for when something has gone wrong already. I don't mean to reduce the need for thorough performance- or scalability reviews, which can still require lots of work and understanding of the customers business. So I definitely don't want the "Modern Troubleshooting" to replace specialist consulting and ongoing (especially pro-active) performance tuning. Of course it is always better to avoid Trouble in the first place.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;STRONG&gt;Identifying Trouble-queries:&lt;/STRONG&gt;&lt;BR&gt;One of the most useful queries I have used for performance troubleshooting recently, is the "TOP 30"- query described here:&lt;BR&gt;&lt;A class="" href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/01/04/simple-query-to-check-the-recent-performance-history.aspx" target=_blank mce_href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/01/04/simple-query-to-check-the-recent-performance-history.aspx"&gt;Simple query to check the recent performance history&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;It returns the queries that are currently in SQL Server's plan cache, sorted with the queries causing most reads at the top. Every time SQL Server generates a query plan, then this plan is stored in this cache. And every time SQL Server (re)uses this plan it will also update some statistics about the plan, like execution_count, number of reads, etc. It is this information that the "TOP 30" query gives you. &lt;/P&gt;
&lt;P&gt;SQL Server's plan cache is changing all the time, depending on what queries SQL Server runs, so you may get different results depending on what time of the day you run the query. The plan cache is also reset when SQL Server restarts, or you can reset the cache by running DBCC FREEPROCCACHE.&lt;/P&gt;
&lt;P&gt;The result of the "TOP 30"-query is easy to copy into an Excel spreadsheet for further analysis, or to send to someone else. So it is simple data to collect, as long as the customer is on SQL2005 or later (Being based on Dynamic Management Views (DMW) which was introduced in SQL Server 2005, it not work for SQL Server 2000).&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What to look at:&lt;/STRONG&gt;&lt;BR&gt;After receiving the result of the query -&amp;nbsp;preferably in an Excel spreadsheet -&amp;nbsp;these are the things I look at:&lt;BR&gt;Being sorted by "max_logical_reads", you have the "worst" query at the top. But also look at execution_count. If a query ran just once, it might have been a batch job, or something else that is not really causing any problems. Of course, queries that have an execution_count in the 100s or 1.000s may be more relevant to look at. Also see if the queries (stetement_text) look similar, or if many of them look to be in the same area (same tables). &lt;/P&gt;
&lt;P&gt;The column diff_quota shows max_logical_reads divided with min_logical_reads. If this number is high, it means that the query plan is inconsistent. This can be either because of inconsistent use of NAV (for example users applying different filters on the same table). Or, because a query plan is good for some queries but bad for others. In this case, some times you can affect the way that SQL Server creates query plans, either by adding RECOMPILE hints, plan guides or index hints. Or by upgrading to a newer version of NAV client (for example see the post "&lt;A class="" href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/04/03/sql-preprocessing-in-sp1.aspx" target=_blank mce_href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/04/03/sql-preprocessing-in-sp1.aspx"&gt;SQL Pre-processing in Microsoft Dynamics NAV 5.0 SP1&lt;/A&gt;"&amp;nbsp;for how NAV 5 SP1 will cause different query plans).&lt;/P&gt;
&lt;P&gt;If diff_quota is low, it means that the query plan is just consistently bad, which means that it is more likely that the query itself is bad. And, you will have to look for reasons why that query consistently causes the number of reads that it does. The "TOP 30"-query can't really help finding out &lt;STRONG&gt;why&lt;/STRONG&gt; a query is causing many reads. But at least it can some times identify which queries to investigate first, which can be a very time consuming task otherwise (collecting and analysing profiler traces, etc).&lt;/P&gt;
&lt;P&gt;You can also look at max_elapsed_time, but keep in mind that when a query takes a long time to run because it is being blocked, then the real problem is somewhere else (in the blocking query). So, if a query has a high max_elapsed_time, then see if the query contains a lock (WITH UPDLOCK). If it does, then you are most likely looking at a blocking problem which requires a wider look, and which often cannot be solved by the query you see.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;So the "TOP 30"-query is always a good place to start. Some times it won't help you solving any problems, but then you will know that without spending much time. Other times, the query tells you right away which queries are causing problems, which can save you a lot of time. So I would always run this query first. And only if it doesn't help, then begin to look at collecting further information.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P&gt;Escalation Engineer&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8493202" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>SQLIndex property</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/04/21/sqlindex-property.aspx</link><pubDate>Mon, 21 Apr 2008 09:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8413941</guid><dc:creator>Lohndorf</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8413941.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8413941</wfw:commentRss><description>&lt;P&gt;In some situations, using the SQLIndex property on a key in Microsoft Dynamics NAV can harm performance. In this blog I &lt;/P&gt;
&lt;P&gt;describe what to be careful about, and why the use of this property has been removed in the NAV 5 SP1 application.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;The property is still available and it is still a valuable tool in performance tuning. But from SP1, it is not used anymore &lt;/P&gt;
&lt;P&gt;in the standard application. The document "Changes in NAV 5 0 SP1.doc" on the SP1 product CD lists the 72 tables where the &lt;/P&gt;
&lt;P&gt;SQLIndex has been removed (Change A222).&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Background:&lt;/STRONG&gt;&lt;BR&gt;The key-property SQLIndex was introduced in NAV version 4 SP1. The idea of the property is to make it possible to change &lt;/P&gt;
&lt;P&gt;the index on the SQL Server while maintaining the same application (same sorting) in NAV.&lt;/P&gt;
&lt;P&gt;The main use of the property is to make the SQL index more selective. In the NAV application there are many keys that begin &lt;/P&gt;
&lt;P&gt;with an option which is not very selective, for example the primary key "Document Type","No." on the Sales Header table. &lt;/P&gt;
&lt;P&gt;"Document Type" - having only 6 possible options - is not very selective, and SQL Server might choose not to use it. If the &lt;/P&gt;
&lt;P&gt;index was changed to be the other way around ("No.","Document Type"), it would be much more selective and more effecient &lt;/P&gt;
&lt;P&gt;for SQL Server to use in SELECT statements.&lt;/P&gt;
&lt;P&gt;The other benefit of this property is to enable "covering indexes", so that you can have a few indexes to cover for most &lt;/P&gt;
&lt;P&gt;searches, and then disable the maintenance of other indexes. For example an index on the "Sales Header" table beginning &lt;/P&gt;
&lt;P&gt;with "No." can be used effeciently with many different filters, reducing the need to have one key for every possible exact filter.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Problems:&lt;/STRONG&gt;&lt;BR&gt;When you have a query which includes an "ORDER BY"-clause, SQL Server has to return the reords in the order specified by &lt;/P&gt;
&lt;P&gt;that clause. If SQL Server doesn't have a matching index, it has to retrieve data using a different index and then do some &lt;/P&gt;
&lt;P&gt;internal sorting to return data in the correct order. If there are no good indexes, then SQL Server may choose to &lt;/P&gt;
&lt;P&gt;use the clustered index which can be bad enough. But when the query also has an index hint, then SQL Server&amp;nbsp;is forced to use the &lt;/P&gt;
&lt;P&gt;index specified by the hint, and this can lead to large amounts of reads.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Example:&lt;/STRONG&gt;&lt;BR&gt;In a recent support case, the customer had generally bad performance. In this case, the "SELECT TOP 30"-query from the post "&lt;A class="" href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/01/04/simple-query-to-check-the-recent-performance-history.aspx" target=_blank mce_href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/01/04/simple-query-to-check-the-recent-performance-history.aspx"&gt;Simple query to check the recent performance history&lt;/A&gt;" showed that out of the top 30 "worst" queries, 26 were similar to this one&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;SELECT TOP 501 * FROM "Reservation Entry" WITH (UPDLOCK, INDEX("$1"))&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;WHERE&lt;/STRONG&gt; (("Source ID"=@P1)) AND (("Source Ref_ &lt;/P&gt;
&lt;P&gt;No_"=@P2)) AND (("Source Type"=@P3)) AND (("Source Subtype"=@P4)) AND (("Source Batch Name"=@P5)) AND (("Source Prod_ Order &lt;/P&gt;
&lt;P&gt;Line"=@P6)) AND (("Reservation Status"=@P7)) &lt;STRONG&gt;ORDER BY&lt;/STRONG&gt; "Source ID","Source Ref_ No_","Source Type","Source Subtype","Source &lt;/P&gt;
&lt;P&gt;Batch Name","Source Prod_ Order Line","Reservation Status","Shipment Date","Expected Receipt Date","Entry No_","Positive" &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;The query itself looks good enough: WHERE-clause and "ORDER BY"-clause match each other, and there were no immediate &lt;/P&gt;
&lt;P&gt;reasons why this query should cause more reads than the number of records in the table. But in the standard application, the SQLIndex property for this key was:&lt;/P&gt;
&lt;P&gt;"Source ID","Entry No.",Positive&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;The idea with this is SQLIndex&amp;nbsp;is to have an index which can cover more situations, and in that way reduce the number of indexes that &lt;/P&gt;
&lt;P&gt;need to be maintained on SQLServer. And the SQLindex is fine for the SELECT-part of the query. The problem is, that the &lt;/P&gt;
&lt;P&gt;index can't be used for the "ORDER BY"-part of the query.&lt;/P&gt;
&lt;P&gt;So what happens, is:&lt;/P&gt;
&lt;P&gt;SQL Server may have planned to use the clustered index to read all data and then do some internal sorting. But in this &lt;/P&gt;
&lt;P&gt;case, the Index Hint forces SQL Server away from that plan. The result is that SQL Server is forced into doing a very &lt;/P&gt;
&lt;P&gt;difficult task while being restricted by the index speicifed by the index hint.&lt;/P&gt;
&lt;P&gt;In this case we designed the "Reservation Entry"-table and removed the SQLIndex property from the key, and performance went &lt;/P&gt;
&lt;P&gt;up.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;STRONG&gt;Conclusion:&lt;/STRONG&gt;&lt;BR&gt;When you see a query which causes many reads, even if SQL Server has a good index, then also consider if the index is &lt;/P&gt;
&lt;P&gt;good for the "ORDER BY"-part of the query. The "ORDER BY"-part of the query depends on the key in NAV. But if the SQLIndex &lt;/P&gt;
&lt;P&gt;property has been set for this key, then by definition, the "ORDER BY" and the SQL index will not be matching.&lt;/P&gt;
&lt;P&gt;You should still consider the use of the SQLIndex property as part of tuning performance of a system. But just be aware that it can also cause problems as described here.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P mce_keep="true"&gt;Escalation Engineer&lt;/P&gt;
&lt;P&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8413941" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>Bulk Inserts in Microsoft Dynamics NAV 5.0 SP1</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/04/14/bulk-inserts-in-microsoft-dynamics-nav-5-0-sp1.aspx</link><pubDate>Mon, 14 Apr 2008 13:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8391767</guid><dc:creator>Lohndorf</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8391767.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8391767</wfw:commentRss><description>&lt;P&gt;Bulk Inserts is a new feature in NAV 5.0 SP1 which is designed to improve performance when inserting multiple records by delaying the physical inserts on the SQL Server.&lt;/P&gt;
&lt;P&gt;Before this change, inserts happen in the order that the C/AL code is running. With Bulk Insert, the NAV-client delays the actual inserts until the last possible moment in the transaction. This means that tables get locked later, so it reduces the amount of time that a table is locked.&lt;/P&gt;
&lt;P&gt;"The last possible moment", means that the inserts will take place just before COMMIT. Or, if you use the return value of the INSERT command (IF Rec.INSERT THEN;). NAV also has to do the inserts if you run any MODIFY, DELETE or&amp;nbsp;FIND methods on the table. So to take full advantage of this feature, you have to consider this when designing a NAV process.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Note: This feature has nothing to do with the Transact SQL command "BULK INSERT". The Bulk Insert all happens on the client. It is not using any special SQL Server features.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;The Pseudo-code below illustrates how you will see the effect of Bulk Insert in a SQL Profiler trace. Without Bulk Insert, the SQL updates may look like this:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;INSERT INTO&lt;/STRONG&gt; "NAV5"."dbo"."CRONUS International Ltd_$G_L Entry"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$Cust_ Ledger Entry"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$G_L REgister"&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;INSERT INTO&lt;/STRONG&gt; "NAV5"."dbo"."CRONUS International Ltd_$G_L Entry"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$Cust_ Ledger Entry"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$G_L REgister"&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;INSERT INTO&lt;/STRONG&gt; "NAV5"."dbo"."CRONUS International Ltd_$G_L Entry"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$Cust_ Ledger Entry"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$G_L REgister"&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;INSERT INTO&lt;/STRONG&gt; "NAV5"."dbo"."CRONUS International Ltd_$G_L Entry"&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;With Bulk Insert, the same C/AL code would look lilke this:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$Cust_ Ledger Entry"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$G_L REgister"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$Cust_ Ledger Entry"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$G_L REgister"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$Cust_ Ledger Entry"&lt;/P&gt;
&lt;P&gt;SELECT TOP 1 FROM "NAV5"."dbo"."CRONUS International Ltd_$G_L REgister"&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;INSERT INTO&lt;/STRONG&gt; "NAV5"."dbo"."CRONUS International Ltd_$G_L Entry"&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;INSERT INTO&lt;/STRONG&gt; "NAV5"."dbo"."CRONUS International Ltd_$G_L Entry"&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;INSERT INTO&lt;/STRONG&gt; "NAV5"."dbo"."CRONUS International Ltd_$G_L Entry"&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;INSERT INTO&lt;/STRONG&gt; "NAV5"."dbo"."CRONUS International Ltd_$G_L Entry"&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;So, you will see exactly the same SQL updates. But with Bulk Insert, the inserts will be accumulated and run at the end of the process.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Lars Lohndorf-Larsen,&lt;/P&gt;
&lt;P mce_keep="true"&gt;Escalation Engineer&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;&lt;FONT size=3&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8391767" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>My experiences with Microsoft Dynamics NAV 5.0 SP1 …</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/04/04/my-experiences-with-microsoft-dynamics-nav-5-0-sp1.aspx</link><pubDate>Fri, 04 Apr 2008 14:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8356647</guid><dc:creator>rmiller</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8356647.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8356647</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;I spent last week performing a Microsoft Dynamics NAV 5.0 Update 1 to Microsoft Dynamics NAV 5.0 SP1 database conversion for a customer.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The process went very smoothly and the customer was very excited about the increase in performance we were able to achieve.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Just as an illustration of our success, the customer ships hundreds of packages a day.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This process has been very painful in the past.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;When the conversion was completed and a little tuning was done, we were able to achieve the following improvements …&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpFirst style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; mso-add-space: auto"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&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;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Arial','sans-serif'"&gt;Create a Shipment --&amp;gt; Reduced by 27%&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; mso-add-space: auto"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&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;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Arial','sans-serif'"&gt;Create a Pick --&amp;gt; Reduced by 15%&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; mso-add-space: auto"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&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;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Arial','sans-serif'"&gt;Register a Pick --&amp;gt; Reduced by 54%&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpLast style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1; mso-add-space: auto"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&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;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Arial','sans-serif'"&gt;Post a Shipment --&amp;gt; Reduced by 53%&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face=Calibri size=3&gt;Now, I mentioned a little tuning was necessary so let me elaborate on that.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;SP1 seems to highlight poor filtering used for the FlowFields.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The tuning that I had to do amounted to determining which CALCSUMS were not performing well.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I did this by using the Client Monitor in the Performance Toolkit.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I was then able to examine the filters that were applied and determine what a more appropriate key would be.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I added the additional key to the table along with the appropriate SumIndexField(s).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;This made all the difference for this customer.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face=Calibri size=3&gt;This customer was also plagued by a large number of locking/blocking issues.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;After applying SP1, with the Bulk Inserts and Indexed Views, the locking/blocking issues became almost non-existent.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Some other pieces of information that might be helpful:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpFirst style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&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;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;Log file size&lt;/B&gt; – during the conversion, the log file did NOT grow at all.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&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;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;Database Size&lt;/B&gt; – when the conversion was done, this particular customer was able to get back approximately 10 GB of free space in the database out of a 65 GB database.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&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;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;Conversion Time&lt;/B&gt; – it took between 40 -60 seconds per GB depending on what hardware was used.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpLast style="MARGIN: 0in 0in 10pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&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;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;Indexed Views&lt;/B&gt; – do NOT add any additional indexes to the Indexed Views.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;When you design the table that the Indexed View is associated with, the view will be dropped and recreated and so will any additional indexes that you might have added.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN-BOTTOM: 0pt"&gt;&lt;SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;&lt;o:p&gt;&lt;FONT size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-BOTTOM: 0pt"&gt;&lt;SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;&lt;FONT size=3&gt;Robert Miller&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;&lt;FONT size=3&gt;Escalation Engineer&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-TOP: 0in"&gt;&lt;SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;&lt;FONT size=3&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;&lt;FONT size=3&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8356647" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/NAV+5.0+Platform+Updates/default.aspx">NAV 5.0 Platform Updates</category></item><item><title>SQL Pre-processing in Microsoft Dynamics NAV 5.0 SP1</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/04/03/sql-preprocessing-in-sp1.aspx</link><pubDate>Thu, 03 Apr 2008 09:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8353210</guid><dc:creator>Lohndorf</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8353210.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8353210</wfw:commentRss><description>&lt;P&gt;One of the major changes in Microsoft Dynamics NAV version 5 SP1 (in relation to performance on SQL Server), is a new way to send queries to SQL Server. In previous versions of NAV, we some times saw SQL Server 2005 optimizing query plans for extreme parameter-values, which - when re-used from cache for queries with other parameter-values - could cause long response time.&amp;nbsp;A behaviour which is described in more details in &lt;A class="" href="https://mbs.microsoft.com/knowledgebase/KBDisplay.aspx?WTNTZSMNWUKNTMMYLSVQUSPTNTNSMQPYTVNSVLONYQVTYPRPTWKOVPUYTXSWTUVP&amp;amp;wa=wsignin1.0" target=_blank mce_href="https://mbs.microsoft.com/knowledgebase/KBDisplay.aspx?WTNTZSMNWUKNTMMYLSVQUSPTNTNSMQPYTVNSVLONYQVTYPRPTWKOVPUYTXSWTUVP&amp;amp;wa=wsignin1.0"&gt;KB 935395&lt;/A&gt; on PartnerSource (login required).&amp;nbsp;Some of the updates for NAV version 4 introduced new features to give better control of the query plans that SQL Server makes, such as index hints and Recompile-option.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;SP1 for NAV version 5 has restructured the way that queries are sent to SQL Server, with the aim that SQL Server will now make query plans that are optimized for average parameter-values rather than extreme parameter-values. It is also&amp;nbsp;a&amp;nbsp;method which lets SQL Server make the plan, without forcing it in a certain direction with index hints or recompile-option.&lt;/P&gt;
&lt;P&gt;Before NAV SP1, a typical query could look like this:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p1 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p1&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;180150033&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p3 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p3&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;2&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p4 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p4&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;1&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p5 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p5&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;0&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff size=2&gt;exec&lt;/FONT&gt;&lt;FONT size=2&gt; sp_cursoropen @p1 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;N&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'SELECT * FROM "Demo Database NAV (5-0)"."dbo"."CRONUS International Ltd_$G_L Entry" WHERE (("G_L Account No_"=@P1)) AND "G_L Account No_"=@P2 AND "Posting Date"=@P3 AND "Entry No_"&amp;gt;=@P4 ORDER BY "G_L Account No_","Posting Date","Entry No_" '&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p3 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p4 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p5 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;N&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'@P1 varchar(20),@P2 varchar(20),@P3 datetime,@P4 int'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;STRONG&gt;'1105'&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;STRONG&gt;'1753-01-01 00:00:00:000'&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;0&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;select&lt;/FONT&gt;&lt;FONT size=2&gt; @p1&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; @p3&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; @p4&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; @p5&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;/FONT&gt;Notice the parameter-values in bold (&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;'1105'&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;STRONG&gt;'1753-01-01 00:00:00:000'&lt;/STRONG&gt;&lt;/FONT&gt;). SQL Server&amp;nbsp;will make a query plan based on running the query with these parameter-values. It will then cache this plan, and use the same plan for other queries which are identical, but have different parameter-values.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In SP1, the query above will look like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p1 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p1&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;1073741861&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p5 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p5&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;12290&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p6 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p6&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;8193&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;exec&lt;/FONT&gt;&lt;FONT size=2&gt; sp_cursorprepare @p1 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;N&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'@P1 varchar(20),@P2 varchar(20)'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;N&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'SELECT * FROM "W1500SP1RTM"."dbo"."CRONUS International Ltd_$G_L Entry" WHERE (("G_L Account No_"=@P1)) AND "G_L Account No_"&amp;gt;@P2 ORDER BY "G_L Account No_","Posting Date","Entry No_" '&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;1&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p5 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p6 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/P&gt;
&lt;P&gt;select&lt;/FONT&gt;&lt;FONT size=2&gt; @p1&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; @p5&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; @p6&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/FONT&gt;
&lt;P&gt;And then another query:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p2 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p2&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;180150031&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p3 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p3&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;2&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p4 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p4&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;1&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @p5 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @p5&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;2&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;exec&lt;/FONT&gt;&lt;FONT size=2&gt; sp_cursorexecute 1073741861&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p2 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p3 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p4 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p5 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'1110'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;select&lt;/FONT&gt;&lt;FONT size=2&gt; @p2&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; @p3&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; @p4&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; @p5&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;So before, we had one query. In SP1 we have two! So what's the benefit of that?&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;If you look at the first query from SP1, notice that it is a sp_cursorprepare statement, and not sp_cursoropen. So the actual query is not run at this point. More importantly, the first query &lt;/FONT&gt;&lt;FONT size=2&gt;does not contain the parameter-values. This is the query for which SQL Server makes the query plan. Not having the parameter-values, SQL Server makes the plan based on&amp;nbsp;its statistics about the data in the table. &lt;/FONT&gt;&lt;FONT size=2&gt;Only after this, NAV then executes the statement in the second query (sp_cursorexecute).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;This method guarantees that SQL Server's query plan will not be affected by the parameter-values. It means that some times, SQL Server is prevented from making the optimum query plan for a certain set of parameter-values. But remember that the query plan will be re-used for other parameter-values. So at the expense of having a few highly optimized queries, the method will give well optimized queries with better consistensy.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;Another cost of this&amp;nbsp;method, is of&amp;nbsp;course that now NAV sends 2 queries instead of 1, requiring an extra roundtrip to SQL Server. But this only happens the first time the query is run. If the same query is run again, NAV will only run the second query (sp_cursorexecute).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;One side effect of this is, that tracing a query in SQL Profiler&amp;nbsp;becomes different. With SP1 you will see a lot of queries like the second one above, which does not show what NAV is actually doing. Take a look at the second query again:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=2&gt;exec&lt;FONT size=2&gt; sp_cursorexecute &lt;STRONG&gt;1073741861&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p2 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p3 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p4 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;@p5 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;output&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'1110'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;/FONT&gt;With&amp;nbsp;SP1 you will see a lot of queries like this, and then wonder what the actual query is. To find out, you need to use the cursor ID, and then find the original sp_cursorprepare statement, which will contain this line:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;set&lt;FONT size=2&gt; @p1&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;1073741861&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=2&gt;and then the actual query.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In summary, this method is designed to give persistently, good overall performance, and to avoid sudden drops in performance that could be the result of cached query plans on SQL Server.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P&gt;Escalation Engineer&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8353210" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>Simple query to check the recent blocking history</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/03/28/simple-query-to-check-the-recent-blocking-history.aspx</link><pubDate>Fri, 28 Mar 2008 10:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8341188</guid><dc:creator>Lohndorf</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/8341188.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=8341188</wfw:commentRss><description>&lt;P&gt;SQL Server 2005 keeps (some) history of the number and time that blocking occurred on indexes. This blog contains a query that queries this information to help identifying on which tables blocking happens most. The query shows accumulated numbers (no. of blocks, wait time, etc) since SQL Server was last restarted.&lt;/P&gt;
&lt;P&gt;The query does have some known in-accuracies. Also, the result needs to be interpreted: It may not point directly at which indexes need changing or disabling. See below for details about this.&lt;/P&gt;
&lt;P&gt;The query uses Dynamic Management Views, which means it&amp;nbsp;will only work from SQL Server 2005 and later.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Make sure to run the query in the NAV database, otherwise you won't see the table names.&lt;/P&gt;
&lt;P&gt;So, here it is:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#008000 size=2&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;--Use [NAV-Database]&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;select&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#ff00ff size=2&gt;db_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;database_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; DB&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;
&lt;P&gt;object_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; Obj&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;--row_lock_count, page_lock_count,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;row_lock_count &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;FONT size=2&gt; page_lock_count No_Of_Locks&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;--row_lock_wait_count, page_lock_wait_count,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;row_lock_wait_count &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;FONT size=2&gt; page_lock_wait_count No_Of_Blocks&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;--row_lock_wait_in_ms, page_lock_wait_in_ms, &lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;row_lock_wait_in_ms &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;FONT size=2&gt; page_lock_wait_in_ms Block_Wait_Time&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;index_id&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;from&lt;/FONT&gt;&lt;FONT size=2&gt; sys.dm_db_index_operational_stats&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(NULL,NULL,NULL,NULL)&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;order&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;by&lt;/FONT&gt;&lt;FONT size=2&gt; Block_Wait_Time &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;desc&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;--order by No_Of_Blocks desc&lt;/P&gt;&lt;/FONT&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Inaccuracies:&lt;BR&gt;No_Of_Blocks is recorded accurately, but the Block_wait_time is not. SQL Server only records Block_wait_time when the block is a clear pagelock or rowlock. It will not record wait_time in case of a rangelock, which is common in NAV. Also, Block_Wait_Time only gets recorded when a transaction completes. So if a transaction is aborted after the block (for example by Lock-Timeout), then Block_Wait_Time for that transaction will not be counted. This means that the real Block_Wait_Time is likely to be higher, and it may be distributed on different tables / indexes than the query shows. Anyway, I hope the query is still accurate enough to give a good idea about where blocking occurs.&lt;/P&gt;
&lt;P&gt;How to interpret the result:&lt;BR&gt;The query shows blocking per index. But you should not put too much importance in the individual index that shows blocking. Instead, look if there may be other indexes in that table which are not used. Remember, an update on Index X may require update on all other indexes in the table. So look at the whole table when deciding if the table is over-indexed. For this, use the query &lt;A class="" href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/02/26/index-usage-query.aspx" target=_blank mce_href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/02/26/index-usage-query.aspx"&gt;"Index Usage"&lt;/A&gt;, which shows you the usage of each index in a table.&lt;/P&gt;
&lt;P&gt;Blocking will happen on the first table in a process which is blocked. Maybe the process begins processing small tables, but the real blocking happens because processing of other tables takes a long time. In that case, the query will show the blocking on the first table, but not show blocking on the later tables, which may be where the real problem is.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I will be more than happy to receive any feedback on&amp;nbsp;experiences with this query, and suggestions for how to improve it!&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P&gt;Escalation Engineer&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;BR&gt;&lt;BR&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8341188" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>Index Usage Query</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/02/26/index-usage-query.aspx</link><pubDate>Tue, 26 Feb 2008 12:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7901298</guid><dc:creator>Lohndorf</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/7901298.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=7901298</wfw:commentRss><description>&lt;P&gt;This is a follow up from an earlier blog &lt;A class="" href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2007/12/10/finding-index-usage.aspx" target=_blank mce_href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2007/12/10/finding-index-usage.aspx"&gt;"Finding Index usage"&lt;/A&gt;. In that blog, I described a very simple way to list how indexes are being used. In this blog, the query is much extended so that it now shows your Navision keys, listed by either number of updates, or by their cost divided by their usage, and it shows when an index was last used for reading. The idea is to show a list of indexes that are being maintained, but never or rarely being used.&lt;/P&gt;
&lt;P&gt;The query uses SQL Server Dynamic Managament Views (DMW), which means it will only work for for SQL Server 2005 and later.&lt;/P&gt;
&lt;P&gt;Feel free to add comments to this blog about how useful (or not) this query is. And about any problems you may find, and suggestions to improve it. All comments will be welcome!&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;To use it, copy the query below into SQL&amp;nbsp;Server Management Studio. Remember to set the database to your Microsoft Dynamics NAV database (not Master or any other database). Then run it. Depending on the size of your database, it may take a few minutes to run it. First time you run it, I would recommend that you do it when the SQL Server is not otherwise busy, until you konw how long it takes:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#008000 size=2&gt;-- use NavisionDB&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;IF&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;OBJECT_ID&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'z_IUQ_Temp_Index_Keys'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'U'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;IS&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NOT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;DROP&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TABLE&lt;/FONT&gt;&lt;FONT size=2&gt; z_IUQ_Temp_Index_Keys&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;IF&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;OBJECT_ID&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'zIUQ_Temp_Index_Usage'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'U'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;IS&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NOT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;DROP&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TABLE&lt;/FONT&gt;&lt;FONT size=2&gt; zIUQ_Temp_Index_Usage&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;-- Generate list of indexes with key list&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;create&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;table&lt;/FONT&gt;&lt;FONT size=2&gt; z_IUQ_Temp_Index_Keys&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[F_Obj_ID] [int] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NOT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[F_Obj_Name] [nvarchar] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;128&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[F_Ind_ID] [int] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NOT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[Index_Column_ID] [int] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NOT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[Index_Key] [nvarchar] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;128&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[Index_Key_List] [nvarchar] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;MAX&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CONSTRAINT&lt;/FONT&gt;&lt;FONT size=2&gt; [z_IUQ_TempPK] &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;PRIMARY&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;KEY&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[F_Obj_ID]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[F_Ind_ID]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[Index_Column_ID] &lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/P&gt;
&lt;P&gt;)&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;Insert&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;into&lt;/FONT&gt;&lt;FONT size=2&gt; z_IUQ_Temp_Index_Keys&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;select&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;),&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;index_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;Index_Column_ID&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;index_col&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;),&lt;/FONT&gt;&lt;FONT size=2&gt;index_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;Index_Column_ID&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;),&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;from&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.index_columns&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#008000 size=2&gt;go&lt;/P&gt;
&lt;P&gt;-- populate key string&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; IndexCursor &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;cursor&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;FOR&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;select&lt;/FONT&gt;&lt;FONT size=2&gt; F_Obj_ID&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; F_Ind_ID &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;from&lt;/FONT&gt;&lt;FONT size=2&gt; z_IUQ_Temp_Index_Keys&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;FOR&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;UPDATE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;of&lt;/FONT&gt;&lt;FONT size=2&gt; Index_Key_List&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @ObjID &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;declare&lt;/FONT&gt;&lt;FONT size=2&gt; @IndID &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/P&gt;
&lt;P&gt;DECLARE&lt;/FONT&gt;&lt;FONT size=2&gt; @KeyString &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;VARCHAR&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;MAX&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; @KeyString &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;open&lt;/FONT&gt;&lt;FONT size=2&gt; IndexCursor&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;nocount&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;on&lt;/P&gt;
&lt;P&gt;fetch&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;next&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;from&lt;/FONT&gt;&lt;FONT size=2&gt; IndexCursor &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;into&lt;/FONT&gt;&lt;FONT size=2&gt; @ObjID&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; @IndID&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;while&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;@@fetch_status&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; 0 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;begin&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SET&lt;/FONT&gt;&lt;FONT size=2&gt; @KeyString &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SELECT&lt;/FONT&gt;&lt;FONT size=2&gt; @KeyString &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;COALESCE&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;@KeyString&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;FONT size=2&gt; Index_Key &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;', '&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;FONT size=2&gt; z_IUQ_Temp_Index_Keys&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;where&lt;/FONT&gt;&lt;FONT size=2&gt; F_Obj_ID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; @ObjID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;and&lt;/FONT&gt;&lt;FONT size=2&gt; F_Ind_ID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; @IndID&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ORDER&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;BY&lt;/FONT&gt;&lt;FONT size=2&gt; F_Ind_ID&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; Index_Column_ID&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SET&lt;/FONT&gt;&lt;FONT size=2&gt; @KeyString &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;LEFT(&lt;/FONT&gt;&lt;FONT size=2&gt;@KeyString&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;LEN&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;@KeyString&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;-&lt;/FONT&gt;&lt;FONT size=2&gt; 2&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;update&lt;/FONT&gt;&lt;FONT size=2&gt; z_IUQ_Temp_Index_Keys&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;set&lt;/FONT&gt;&lt;FONT size=2&gt; Index_Key_List &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; @KeyString&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;where&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;current&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;of&lt;/FONT&gt;&lt;FONT size=2&gt; IndexCursor&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;fetch&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;next&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;from&lt;/FONT&gt;&lt;FONT size=2&gt; IndexCursor &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;into&lt;/FONT&gt;&lt;FONT size=2&gt; @ObjID&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; @IndID&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;end&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;close&lt;/FONT&gt;&lt;FONT size=2&gt; IndexCursor&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;deallocate&lt;/FONT&gt;&lt;FONT size=2&gt; IndexCursor&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;-- Generate list of Index usage&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;create&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;table&lt;/FONT&gt;&lt;FONT size=2&gt; zIUQ_Temp_Index_Usage&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[F_Table_Name] [nvarchar]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;128&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NOT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[F_Ind_ID] [int] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NOT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[F_Index_Name] [nvarchar]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;128&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[No_Of_Updates] [int] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[User_Reads] [int] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[Last_Used_For_Reads] [datetime] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[Index_Type] [nvarchar]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;56&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NOT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[last_user_seek] [datetime] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[last_user_scan] [datetime] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[last_user_lookup] [datetime] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL,&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;
&lt;P&gt;[Index_Keys] [nvarchar] &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;255&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NULL&lt;/P&gt;
&lt;P&gt;)&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;insert&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;into&lt;/FONT&gt;&lt;FONT size=2&gt; zIUQ_Temp_Index_Usage&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;select&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;
&lt;P&gt;object_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; Table_Name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;index_id Index_ID&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;SI&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;name Index_Name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;user_updates No_Of_Updates&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;user_seeks &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;FONT size=2&gt; US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;user_scans &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;FONT size=2&gt; US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;user_lookups User_Reads&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;case&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;when&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;ISNULL&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_seek&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'00:00:00.000'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;ISNULL&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_scan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'00:00:00.000'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;))&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;and&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;ISNULL&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_seek&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'00:00:00.000'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;ISNULL&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_lookup&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'00:00:00.000'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;))&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;then&lt;/FONT&gt;&lt;FONT size=2&gt; US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_seek&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;when&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;ISNULL&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_scan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'00:00:00.000'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;ISNULL&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_seek&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'00:00:00.000'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;))&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;and&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;ISNULL&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_scan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'00:00:00.000'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;ISNULL&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_lookup&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'00:00:00.000'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;))&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;then&lt;/FONT&gt;&lt;FONT size=2&gt; US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_scan &lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;else&lt;/FONT&gt;&lt;FONT size=2&gt; US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_lookup&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;end&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;FONT size=2&gt; Last_Used_For_Reads&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;SI&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;type_desc Index_Type&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_seek&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_scan&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;last_user_lookup&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;
&lt;P&gt;''&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;from&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.dm_db_index_usage_stats&lt;/FONT&gt;&lt;FONT size=2&gt; US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.indexes&lt;/FONT&gt;&lt;FONT size=2&gt; SI &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;where&lt;/FONT&gt;&lt;FONT size=2&gt; SI&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_id&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_id&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;and&lt;/FONT&gt;&lt;FONT size=2&gt; SI&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;index_id &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; US&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;index_id&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;order&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;by&lt;/FONT&gt;&lt;FONT size=2&gt; No_Of_Updates &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;desc&lt;/P&gt;
&lt;P mce_keep="true"&gt;go&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;-- Select and join the two tables.&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;select&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;
&lt;P&gt;TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;F_Table_Name Table_Name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;--TIU.F_Ind_ID Index_ID,&lt;/P&gt;
&lt;P&gt;--TIU.F_Index_Name Index_Name,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;TIK&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;Index_Key_List&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;No_Of_Updates&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;User_Reads&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;when&lt;/FONT&gt;&lt;FONT size=2&gt; TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;User_Reads &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; 0 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;then&lt;/FONT&gt;&lt;FONT size=2&gt; TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;No_Of_Updates&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;else&lt;/FONT&gt;&lt;FONT size=2&gt; TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;No_Of_Updates &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;/&lt;/FONT&gt;&lt;FONT size=2&gt; TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;User_Reads&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;end&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;FONT size=2&gt; Cost_Benefit&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;Last_Used_For_Reads&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;Index_Type&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;from&lt;/FONT&gt;&lt;FONT size=2&gt; zIUQ_Temp_Index_Usage TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt; z_IUQ_Temp_Index_Keys TIK &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;where&lt;/FONT&gt;&lt;FONT size=2&gt; TIK&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;F_Obj_Name &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;F_Table_Name &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;and&lt;/FONT&gt;&lt;FONT size=2&gt; TIK&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;F_Ind_ID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;F_Ind_ID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;and&lt;/FONT&gt;&lt;FONT size=2&gt; TIK&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;Index_Column_ID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt; 1&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;
&lt;P&gt;and&lt;/FONT&gt;&lt;FONT size=2&gt; TIU&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;F_Table_Name &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;not&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;in&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'zIUQ_Temp_Index_Usage'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'z_IUQ_Temp_Index_Keys'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;order&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;by&lt;/FONT&gt;&lt;FONT size=2&gt; No_Of_Updates &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;desc&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;
&lt;P&gt;--order by Cost_Benefit desc&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/FONT&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The query will show you one line for each index in the SQL Database. It shows you the&amp;nbsp;table name, and a list of fields in the index. Note that any non-clustered index also contain the clustered index. For example on SQL Server, the key "Document No." in the "Cus. Ledger Entry table" is "Document No.","Entry No.". Also note that the indexes shown by SQL Server is not always shown in the same order as you have defined them in NAV.&lt;/P&gt;
&lt;P&gt;The column "No_Of_Updates" basically&amp;nbsp;shows you the cost of this index, since every update requires a lock as well as a write to the database. The next column, "User_Reads", shows you how often this index has been used, either from the UI, or by C/AL code. Compare these two, and you have way to compare the cost against the benefits of each index, as shown in the column "Cost_Benefit", which is simply "No_Of_Updates" / "User_Reads". The column "Last_Used_For_Reads" shows you when an index was actually used for reading.&lt;/P&gt;
&lt;P&gt;The query sorts the indexes by "No_Of_Updates", with the most updated (most costly) index first. At the last line of the query you can change the sorting to "order by Cost_Benefit desc", and you are likely to see a different picture.&lt;/P&gt;
&lt;P&gt;Finally, the query shows you whether each index is clustered or non-clustered. &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;The query will create two new tables called "z_IUQ_Temp_Index_Keys" and "zIUQ_Temp_Index_Usage". Although highly unlikely, if you already have tables with these names in your database, then the query will overwrite those without warnings. These tables collect index usage statistics, so if you&amp;nbsp;need to run the query again, for example because you lost the results, or wat to run it with a different sorting, you don't have to run the whole query. Just run the last part of the query - from the section&amp;nbsp; "&lt;FONT color=#008000 size=2&gt;-- Select and join the two tables.&lt;/FONT&gt;", and it will run much faster. Only&amp;nbsp;after you change indexes, or want an updated view of index usage, you need to run the whole query again.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The data shown by the query is reset every time SQL Server restarts. So if you have recently restarted SQL Server, then the query may not show you the most precise picture of how the indexes are being used over time. Also consider that some indexes may only ever be used for example at end of the month / end of fiscal year, etc. So just because the query shows that a certain index was not used since SQL Server was last restarted, then this index may still be required for specific jobs.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P&gt;Escalation Engineer&lt;/P&gt;
&lt;P&gt;These postings&amp;nbsp;are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7901298" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>How to detect locking order for a NAV process</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/02/20/how-to-detect-locking-order-for-a-nav-process.aspx</link><pubDate>Wed, 20 Feb 2008 14:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7816142</guid><dc:creator>Lohndorf</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/7816142.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=7816142</wfw:commentRss><description>&lt;P&gt;The nature of a deadlock is that two processes lock resources in different orders. Deadlocks can in theory be eliminated by ensuring that all processes always lock resources in the same order. This document describes how to determine the locking order of a process in Microsoft Dynamics NAV.&lt;/P&gt;
&lt;P&gt;Note, that I mention locking of "resources". For most of the time, this means placing locks on a table, but it could as well mean placing locks on different parts of the same table, or of different indexes in the same, or two different tables. But then we are into micro-tuning, so for this post, when I say "Resource", I mean "Table".&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;What is a deadlock:&lt;BR&gt;A deadlock will return an error message which specifically says that your activity was deadlocked. The deadlock error-message will read:&lt;/P&gt;
&lt;P&gt;"Your activity was deadlocked with another user modifying the [xyz] table.&lt;BR&gt;Start again."&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;A blocking chain is a situation where a client hangs (becomes unresponsive) until a resource becomes available. In common language you could describe such a situation as a deadlock situation. But technically, this is &lt;STRONG&gt;not&lt;/STRONG&gt; a deadlock, since the situation will be resolved eventually. In other words, to any user, an infinite block may look like a deadlock. But if you have deadlocks, then by definition, your users will have deadlock-error messages like the one shown above. One of the first steps in troubleshooting any kind of locking or blocking is to identify exactly what type of problem you have. So always make sure to first find out whether you are dealing with blocking chains, deadlocks, or other issues, since selecting the best troubleshooting methods depend on what exact issue you are looking at.&lt;/P&gt;
&lt;P&gt;This post shows how to determine the locking order of a process in NAV. Knowing the locking order of various processes can help identifying potential deadlocks. It can also help in cases where you know that two or more different processes are causing deadlocks, by showing the locking order of each of these processes.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;U&gt;Pre-requisites:&lt;/U&gt;&lt;BR&gt;The tool described here is part of the Performance Troubleshooting Guide, which is available on &lt;A class="" href="https://mbs.microsoft.com/partnersource/products/navision/documentation/benchmarks/navisionsqlresourcekit.htm?printpage=false" target=_blank mce_href="https://mbs.microsoft.com/partnersource/products/navision/documentation/benchmarks/navisionsqlresourcekit.htm?printpage=false"&gt;PartnerSource&lt;/A&gt;&amp;nbsp;(partner login required). The tools described here require a NAV Partner license.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;The SQL Server Performance Troubleshooting Guide,&amp;nbsp;includes an object called "Client Monitor.fob". To begin, import this into the database which contain the processes that you are troubleshooting. It does not have to be a live database - a stand-alone copy of a live database is all you need. In this scenario you are examining locking orders of processes which can be done as well in your office, on a copy or test-version of a database, as in a production environment.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;To use "Client Monitor.fob", follow these steps, after importing it into the database:&lt;/P&gt;
&lt;P&gt;1.&amp;nbsp; Start Client Monitor (Tools -&amp;gt; Client monitor -&amp;gt; Start). Before starting it, go to the Options tab and de-select "Include Object table activity", and select all the options under "Advanced".&lt;BR&gt;2.&amp;nbsp; Run the processes for which you want to detect the locking order.&lt;BR&gt;3.&amp;nbsp; Stop "Client Monitor".&lt;BR&gt;4.&amp;nbsp; Run form 150025 "Transactions" which was imported in "Client MOnitor.fob". This will take a while, while it collects the information that was collected by the Client Monitor. When it opens, it will show you one line for each transaction.&lt;BR&gt;5.&amp;nbsp; For each of the lines shown in this form, click on Transaction -&amp;gt; "Locking order" to see the locking order of each transaction.&lt;/P&gt;
&lt;P&gt;This shows you&amp;nbsp;not just the locking order of each transaction, but you will also see the C/AL code that places the lock. If you compare this information with knowledge of what tables and processes are involved in the deadlocks you are troubleshooting, it can help you decide where locking orders need to be changed.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;U&gt;&lt;/U&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;U&gt;What locks a record?&lt;BR&gt;&lt;/U&gt;NAV will automatically place a lock as soon as any update command is used (INSERT, MODIFY, DELETE), even if the C/AL command LOCKTABLE is not used. On SQL Server, Navision will only lock the record (and potentially adjacent records - &lt;A class="" href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/02/06/record-level-locking-in-the-sql-server-option-for-microsoft-dynamics-nav.aspx" target=_blank mce_href="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/02/06/record-level-locking-in-the-sql-server-option-for-microsoft-dynamics-nav.aspx"&gt;see this post&lt;/A&gt;). &lt;/P&gt;
&lt;P&gt;The C/AL command LOCKTABLE in itself does not lock anything. It only puts NAV into locking-mode. Navision will then lock any records that it accesses. This is why the places in C/AL code that place locks are typically not LOCKTABLE-commands, but for example a FIND('-')-command that comes &lt;EM&gt;after&lt;/EM&gt; a LOCKTABLE command.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;BR&gt;&lt;U&gt;What to do next:&lt;/U&gt;&lt;BR&gt;Once you have determined that two different processes have different locking orders, you must decide on a locking order. There are no complete guides to which order should be used, but if you look for the C/AL command RECORDLEVELLOCKING in codeunit 80, you can see that this codeunit locks a number of tables in a certain order. At least for tables that are included in this order, it makes sense to stick to this order. For tables which are not included here, you must make your own decisions. Once you have decided on a locking order, you can use one of the following tactics to change it:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;U&gt;Avoid locking:&lt;/U&gt;&lt;BR&gt;Some times it is not necessary for a process to access certain tables. For example, the tool may show that table 5765 – “Warehouse Request” is being locked. If a customer is not using warehousing, then the code that locks this table can some times be remarked.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Lock sooner or later:&lt;/U&gt;&lt;BR&gt;One of the most common ways to change locking order is to move a lock up so that it happens sooner in the process. For example, lets say you have this line of code:&lt;BR&gt;&amp;nbsp; SalesOrder.INSERT;&lt;BR&gt;And you know that later on in the code, you will be locking one of your own tables. To change the locking order of these two tables, add:&lt;BR&gt;&amp;nbsp; YourOwnTale.LOCKTABLE;&lt;BR&gt;Before the line where you lock the Sales Order table.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;U&gt;Master lock (semaphore):&lt;/U&gt;&lt;BR&gt;You can decide that all processes must lock a certain record before they lock anything else. In this case, only 1 process will run at the time. This will effectively eliminate any deadlocking, but it will also reduce concurrency, and can lead to blocking chains instead.&lt;BR&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;As you can see, two of the tactics above (lock sooner, and Master lock) may reduce the risk of deadlocks. But on the other hand they can also increase blocks, because (more) resource(s) get locked sooner. So always make a total assessment of the problem that deadlocks cause. Some times it may be better to have a weekly deadlock, but optimistic locking, than begin to rearrange locks and cause more blocks.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P&gt;Escalation Engineer&lt;/P&gt;
&lt;P&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7816142" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item><item><title>Record-level locking in the SQL Server option for Microsoft Dynamics NAV</title><link>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/2008/02/06/record-level-locking-in-the-sql-server-option-for-microsoft-dynamics-nav.aspx</link><pubDate>Wed, 06 Feb 2008 11:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7486349</guid><dc:creator>Lohndorf</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/comments/7486349.aspx</comments><wfw:commentRss>http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/commentrss.aspx?PostID=7486349</wfw:commentRss><description>&lt;P&gt;If you are designing a system for high throughput and want to minimize blocking, it's important to know in advance exactly what kind of locking behaviour to expect. &lt;/P&gt;
&lt;P&gt;On SQL Server, Microsoft Dynamics NAV uses record-level locking, as opposed to table-level locking on the native database server. In reality, SQL Server can lock a little bit more than the individual records you want to lock: It can also lock the next and the previous records. This happens when SQL Server applies a range-lock.&lt;/P&gt;
&lt;P&gt;This post describes how and when a range-lock can occur. It applies to a normal lock, regardless of the "Always Rowlock"-setting in NAV, and lock escalation where SQL Server can escalate a record-level lock to a table-lock - these are seperate issues.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Here are some examples:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Table 7 "Standard Text", contains the following records:&lt;BR&gt;Code Description&lt;BR&gt;MD&amp;nbsp;&amp;nbsp;&amp;nbsp; Monthly Depreciation&lt;BR&gt;SC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Shipping Charge&lt;BR&gt;SUC&amp;nbsp; Sale under Contract&lt;BR&gt;TE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Travel Expenses&lt;/P&gt;
&lt;P&gt;Table 7 is used here, because it is the simplest possible table.&lt;/P&gt;
&lt;P&gt;The following C/AL code in NAV will lock just one record (SC - Shipping Charge):&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;OnRun()&lt;BR&gt;StandardText.LOCKTABLE;&lt;BR&gt;StandardText.GET('SC');&lt;/P&gt;
&lt;P&gt;IF NOT CONFIRM('Continue?') THEN&lt;BR&gt;&amp;nbsp; ERROR('Stopped.');&lt;/P&gt;
&lt;P&gt;You can confirm this by running it from one client, then open another client and try to update the records in the table.&lt;/P&gt;
&lt;P&gt;Now, consider this C/AL code:&lt;/P&gt;
&lt;P&gt;StandardText.LOCKTABLE;&lt;BR&gt;StandardText.SETFILTER(Code,'S*');&lt;BR&gt;StandardText.FINDSET;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;You might expect that it will lock the two records that fall within this filter (S*): SC and SUC. But this is where SQL Server locks a bit more: It will also lock the records around this filter (MD and TE). This is because as soon as the lock covers a range and not just one individual record, SQL Server has to protect not only the locked records, but also the range itself. In this case, the range covers 2 records, and SQL Server prevents anyone else from inserting new records in this range. It is SQL Server's way to guarantee that the range stays at these 2 records.&lt;/P&gt;
&lt;P&gt;Depending on your C/AL code, some times SQL Server protects just the beginning, and some times just the end of the range, and some times both the beginning and the end. So when you lock a range, you should assume that that both the record just before, and just after, will also get locked.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Here is an example from a more real situation. Imagine you have a process to update sales order 2002 (posting / releasing or any other process). You may have C/AL code to lock the sales lines, like this:&lt;/P&gt;
&lt;P&gt;SalesLine.SETRANGE("Document Type",SalesLine."Document Type"::Order);&lt;BR&gt;SalesLine.SETRANGE("Document No.",'2002');&lt;BR&gt;SalesLine.LOCKTABLE;&lt;BR&gt;SalesLine.FINDSET;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;In this case, also the lines for order 2003 will get locked! So even when users are working on their own documents, they can still end up blocking each other.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;BR&gt;&lt;STRONG&gt;When&amp;nbsp;this is causing problems, what methods can be used?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The simple answer is, to make sure that users don't work on records that are just next to each others. One way would be to insert "ghost" records between each normal record. Another way, is to change the sorting. In the example above, if you had added this line at the beginning:&lt;BR&gt;SalesLine.SETCURRENTKEY("Document Type","Sell-to Customer No.");&lt;/P&gt;
&lt;P&gt;Then order 2003 will not get locked, because with this sorting, it is not the next record.Or you can design a solution that works in more random areas of a table. Using Number Series means that active documents are often in the same area of the table. If you use random numbers, or GUID as primary keys, then the active documents would be spread through the whole table, and the risk of users updating records next to each other, would be smaller.&lt;/P&gt;
&lt;P&gt;These are just some methods to consider, but the main aim would be to spread activity on a contented table to avoid hot-spots in that table.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;STRONG&gt;Open-ended ranges&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Locking the last record is used in a number of places in the NAV application, including the posting routines, which normally lock the last record in the entry table. When the record you are locking is the last one in the table, then the "next record" is anywhere between the last record and infinity. So in this case, the range that is locked can become much larger. &lt;/P&gt;
&lt;P&gt;&lt;BR&gt;If we go back to the Standard Text table and run this C/AL code:&lt;BR&gt;StandardText.LOCKTABLE;&lt;BR&gt;StandardText.FINDLAST;&lt;/P&gt;
&lt;P&gt;Then the locked range will include any possible record after the last one (TE - Travel Expenses), so it will prevent from inserting any new records that would come after TE.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If designing an application from scratch, then you may want to take this behaviour into consideration. If changing an existing application, then in some cases it will require major re-design. So always also consider other ways to improve performance. There may be easier ways to resolve blocking problems.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lars Lohndorf-Larsen&lt;/P&gt;
&lt;P&gt;Escalation Engineer&lt;/P&gt;
&lt;P&gt;These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7486349" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/microsoft_dynamics_nav_sustained_engineering/archive/tags/2005+performance/default.aspx">2005 performance</category></item></channel></rss>