<?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>SQL Server Engine Tips : Dynamic Management View</title><link>http://blogs.msdn.com/sqltips/archive/tags/Dynamic+Management+View/default.aspx</link><description>Tags: Dynamic Management View</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>OBJECT_NAME enhancement and OBJECT_SCHEMA_NAME addition in SQL Server 2005 SP2</title><link>http://blogs.msdn.com/sqltips/archive/2007/03/23/object-name-enhancement-and-object-schema-name-addition-in-sql-server-2005-sp2.aspx</link><pubDate>Sat, 24 Mar 2007 02:24:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1939683</guid><dc:creator>SQL Server Engine Team</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/sqltips/comments/1939683.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqltips/commentrss.aspx?PostID=1939683</wfw:commentRss><wfw:comment>http://blogs.msdn.com/sqltips/rsscomments.aspx?PostID=1939683</wfw:comment><description>&lt;p&gt;SQL Server 2005 SP2 has an important enhancement to OBJECT_NAME metadata function and a new OBJECT_SCHEMA_NAME metadata function. I will first describe the old functionality to give some context and demonstrate how the new features help a lot.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Please note that the examples uses DMVs that looks at metadata in each database or plan cache&amp;nbsp;so performance of the queries depends on your environment, number of objects in the database, auto open/auto close setting of database, size of buffer pool or plan cache&amp;nbsp;etc. So exercise caution if you run the query on a production database and it might be prudent just to restrict it to a specific database to see the results.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The OBJECT_NAME function is typically used to get the name of an object by specifying the object identifier (object_id value). For example, the query below returns the usage stats of indexes in the AdventureWorks database:&lt;/p&gt; &lt;p&gt;select OBJECT_NAME(i.object_id) as object_name, *&lt;br&gt;from sys.dm_db_index_usage_stats as i&lt;br&gt;where i.database_id = db_id('AdventureWorks'); &lt;/p&gt; &lt;p&gt;Now, the above query will return the correct object name only if the query was run in the AdventureWorks database. This is because the metadata function OBJECT_NAME&amp;nbsp;is database specific and uses information from the catalog tables in the current database. If you run the query in a different database (say master) then the names will either be wrong (because object_id may match a different object in master database) or NULL. So in order to get the correct object name, the query has to be executed in the context of the database you are interested (AdventureWorks in our example).&lt;/p&gt; &lt;p&gt;This DMV also returns information from multiple databases on the server. Let us now consider a scenario where you want to write a single query that returns say the top 5 entries from each database based on the number of user seeks that were performed on the index. The query will look like below:&lt;/p&gt; &lt;p&gt;select *&lt;br&gt;from (&lt;br&gt;&amp;nbsp;select *, DENSE_RANK() OVER(PARTITION by database_id ORDER BY user_seeks DESC) as rnk&lt;br&gt;&amp;nbsp;from sys.dm_db_index_usage_stats&lt;br&gt;) as i&lt;br&gt;where i.rnk &amp;lt;= 5;&lt;/p&gt; &lt;p&gt;To modify the query to return the user friendly object names instead of the identifiers, you will have to use dynamic SQL in older versions of SQL Server. This is because the OBJECT_NAME function always worked within the context of the current database. SQL Server 2005 SP2 removes this restriction and we now have an additional optional parameter that specifies the database id. This allows us to write a single query that can retrieve the OBJECT_NAME given the object identifier and database identifier of object in any database in a server. The modified query that lists the entries along with the object names is shown below:&lt;/p&gt; &lt;p&gt;select OBJECT_NAME(i.object_id, i.database_id) as objname, *&lt;br&gt;from (&lt;br&gt;&amp;nbsp;select *, DENSE_RANK() OVER(PARTITION by database_id ORDER BY user_seeks DESC) as rnk&lt;br&gt;&amp;nbsp;from sys.dm_db_index_usage_stats&lt;br&gt;) as i&lt;br&gt;where i.rnk &amp;lt;= 5;&lt;/p&gt; &lt;p&gt;Can you see how simple it is now to write queries that involve looking at object metadata in multiple databases? The enhancement to OBJECT_NAME now allows you to write complex queries that look at metadata in different databases without using dynamic SQL.&lt;/p&gt; &lt;p&gt;Lastly to round off the post, SQL Server 2005 has user schema separation and supports the ANSI SQL model of schemas. So it is always better to return object names along with their schema names. The OBJECT_SCHEMA_NAME metadata function can be used to return the schema name of a schema-scoped object like table or view by specifying the object identifier and optionally database identifier. The modified query below shows how to list the schema name also:&lt;/p&gt; &lt;p&gt;select OBJECT_SCHEMA_NAME(i.object_id, i.database_id) as schname&lt;br&gt;, OBJECT_NAME(i.object_id, i.database_id) as objname&lt;br&gt;, *&lt;br&gt;from (&lt;br&gt;&amp;nbsp;select *, DENSE_RANK() OVER(PARTITION by database_id ORDER BY user_seeks DESC) as rnk&lt;br&gt;&amp;nbsp;from sys.dm_db_index_usage_stats&lt;br&gt;) as i&lt;br&gt;where i.rnk &amp;lt;= 5;&lt;/p&gt; &lt;p&gt;The final query that shows the full object names along with the database in quoted format is shown below. The query lists the top 5 indexes in each database that had the most number of user_seeks performed.&lt;/p&gt; &lt;p&gt;select QUOTENAME(DB_NAME(i.database_id), '"')&lt;br&gt;+ N'.'&lt;br&gt;+ QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id, i.database_id), '"')&lt;br&gt;+ N'.'&lt;br&gt;+ QUOTENAME(OBJECT_NAME(i.object_id, i.database_id), '"') as full_obj_name, *&lt;br&gt;from (&lt;br&gt;&amp;nbsp;select *, DENSE_RANK() OVER(PARTITION by database_id ORDER BY user_seeks DESC) as rnk&lt;br&gt;&amp;nbsp;from sys.dm_db_index_usage_stats&lt;br&gt;) as i&lt;br&gt;where i.rnk &amp;lt;= 5&lt;br&gt;order by i.database_id, i.rnk;&lt;/p&gt; &lt;p&gt;Below are some more examples on how to use the new functions.&lt;/p&gt; &lt;p&gt;-- Returns top 5 fragmented indexes in each database:&lt;/p&gt; &lt;p&gt;select QUOTENAME(DB_NAME(i.database_id), '"')&lt;br&gt;+ N'.'&lt;br&gt;+ QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id, i.database_id), '"')&lt;br&gt;+ N'.'&lt;br&gt;+ QUOTENAME(OBJECT_NAME(i.object_id, i.database_id), '"') as full_obj_name&lt;br&gt;, *&lt;br&gt;from (&lt;br&gt;&amp;nbsp;select *, DENSE_RANK() OVER(PARTITION by database_id ORDER BY avg_fragmentation_in_percent DESC) as rnk&lt;br&gt;&amp;nbsp;from sys.dm_db_index_physical_stats(default, default, default, default, default)&lt;br&gt;&amp;nbsp;where avg_fragmentation_in_percent &amp;gt; 0&lt;br&gt;) as i&lt;br&gt;where i.rnk &amp;lt;= 5&lt;br&gt;order by i.database_id, i.rnk;&lt;/p&gt; &lt;p&gt;-- Returns top 10 statements (in sql modules) per database that took the most elapsed time:&lt;/p&gt; &lt;p&gt;select coalesce(QUOTENAME(DB_NAME(t.dbid), '"'), '') /* NULL means resource db*/&lt;br&gt;+ N'.'&lt;br&gt;+ QUOTENAME(OBJECT_SCHEMA_NAME(t.objectid, t.dbid), '"')&lt;br&gt;+ N'.'&lt;br&gt;+ QUOTENAME(OBJECT_NAME(t.objectid, t.dbid), '"') as full_obj_name&lt;br&gt;, SUBSTRING(t.text, (t.statement_start_offset/2)+1, &lt;br&gt;((CASE t.statement_end_offset&lt;br&gt;WHEN -1 THEN DATALENGTH(t.text)&lt;br&gt;ELSE t.statement_end_offset&lt;br&gt;END - t.statement_start_offset)/2) + 1) AS statement_text&lt;br&gt;, t.*&lt;br&gt;from (&lt;br&gt;&amp;nbsp;select *, DENSE_RANK() OVER(PARTITION BY t.dbid ORDER BY qs.total_elapsed_time) as rnk&lt;br&gt;&amp;nbsp;from sys.dm_exec_query_stats as qs&lt;br&gt;&amp;nbsp;cross apply sys.dm_exec_sql_text(qs.sql_handle) as t&lt;br&gt;&amp;nbsp;where t.objectid is not null&lt;br&gt;) as t&lt;br&gt;where t.rnk &amp;lt;= 10&lt;br&gt;order by t.dbid, t.rnk;&lt;/p&gt; &lt;p&gt;Hope you find these enhancements in SQL Server 2005 SP2 useful and productive. Feel free to comment if you need more examples or more use cases.&lt;/p&gt; &lt;p&gt;--&lt;/p&gt; &lt;p&gt;Umachandar&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1939683" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqltips/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.msdn.com/sqltips/archive/tags/Dynamic+Management+View/default.aspx">Dynamic Management View</category></item><item><title>Find Top N costly query plans in adhoc batches or modules...</title><link>http://blogs.msdn.com/sqltips/archive/2005/10/05/Top-N-costly-query-plans.aspx</link><pubDate>Thu, 06 Oct 2005 04:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:477613</guid><dc:creator>SQL Server Engine Team</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/sqltips/comments/477613.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqltips/commentrss.aspx?PostID=477613</wfw:commentRss><wfw:comment>http://blogs.msdn.com/sqltips/rsscomments.aspx?PostID=477613</wfw:comment><description>&lt;DIV&gt;I encountered a problem about a query not using a particular indexed view in SQL Server 2005. To investigate this issue, I figured that I would go about writing a query using the execution related dynamic dynamic management views to get the cost of the query that should have used the indexed view. This proved to be an interesting adventure that also revealed some inconsistencies in how we expose certain metadata in the DMVs. On the bright side, the final query showcases the powerful new relational, TSQL and XQuery features of SQL Server 2005.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Let's start with brief outline of the DMVs that I planned to use:&lt;BR&gt;&lt;/DIV&gt;
&lt;UL&gt;
&lt;LI&gt;sys.dm_exec_query_stats - Returns performance statistics for cached query plans. This contains one row per query plan so if a stored procedure or batch contains two SELECT statements you may get two rows here 
&lt;LI&gt;sys.dm_exec_sql_text - Returns the text of the sql statement based on the SQL handle 
&lt;LI&gt;sys.dm_exec_query_plan - Returns the showplan in XML format for a batch or module based on the plan handle&lt;BR&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;DIV&gt;A simple query to get the elapsed time counters and SQL text of the batch/module is shown below. This query uses the new APPLY operator to join with a table-valued function passing the sql_handle value for each row.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;select qs.sql_handle, qs.execution_count&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, qs.total_elapsed_time, qs.last_elapsed_time&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qs.min_elapsed_time, qs.max_elapsed_time&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qs.total_clr_time, qs.last_clr_time&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, qs.min_clr_time, qs.max_clr_time&lt;BR&gt;&amp;nbsp; from sys.dm_exec_query_stats as qs&lt;BR&gt;&amp;nbsp;cross apply sys.dm_exec_sql_text(qs.sql_handle) as st&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;This query can be modified to return the actual statement for which the stats are returned using the offset columns in sys.dm_exec_query_stats. Please note that the statement_start_offset and statement_end_offset columns are zero based, represents number of bytes and the end offset is -1 for last statement in the batch. In addition the text value returned by sys.dm_exec_sql_text is nvarchar(max) instead of text as documented incorrectly in Books Online. The modified query that accounts for these quirks is shown below:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;select qs.sql_handle, qs.execution_count 
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, qs.total_elapsed_time, qs.last_elapsed_time&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qs.min_elapsed_time, qs.max_elapsed_time&lt;BR&gt;&lt;/FONT&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qs.total_clr_time, qs.last_clr_time&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, qs.min_clr_time, qs.max_clr_time&lt;BR&gt;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , substring(st.text, (qs.statement_start_offset/2)+1&lt;/FONT&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , ((case qs.statement_end_offset&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when -1 then datalength(st.text)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else qs.statement_end_offset&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end - qs.statement_start_offset)/2) + 1) as statement_text&lt;BR&gt;&amp;nbsp; from sys.dm_exec_query_stats as qs&lt;BR&gt;&amp;nbsp;cross apply sys.dm_exec_sql_text(qs.sql_handle) as st&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Next, a similar query that gets the elapsed time counters and the XML showplan output for the batch/module.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;select qs.sql_handle, qs.execution_count&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, qs.total_elapsed_time, qs.last_elapsed_time&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qs.min_elapsed_time, qs.max_elapsed_time&lt;BR&gt;&lt;/FONT&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qs.total_clr_time, qs.last_clr_time&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, qs.min_clr_time, qs.max_clr_time&lt;BR&gt;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qp.query_plan&lt;BR&gt;&amp;nbsp; from sys.dm_exec_query_stats as qs&lt;BR&gt;&amp;nbsp;cross apply sys.dm_exec_query_plan (qs.plan_handle) as qp&lt;/FONT&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Note that as I mentioned above, sys.dm_exec_query_stats returns a row for each query plan in a batch/module. The showplan output on the other hand contains the entire plan in XML format with each statement identified by the StatementID attribute which is simply a counter starting from the first statement in a batch. For example, if a stored procedure contains two queries then there will be two entries in the XML plan - one with StatementID = 1 and another with StatementID = 2. If there are additional variable&amp;nbsp;assignments statements or DDLs or other TSQL statements they are also numbered appropriately in the order of appearance.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Consider the example stored procedure below:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;create procedure TestProc&lt;BR&gt;as&lt;BR&gt;begin&lt;BR&gt;&amp;nbsp;declare @spid int&lt;BR&gt;&amp;nbsp;set @spid = @@spid&lt;BR&gt;&amp;nbsp;select count(*) from master.sys.sysprocesses where spid = @spid&lt;BR&gt;&amp;nbsp;select count(*) from master.sys.syslockinfo where req_spid = @spid&lt;BR&gt;end&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The showplan output will contain&amp;nbsp;3 StmtSimple nodes (fragments shown below with StatementText, StatementType and StatementId attributes only):&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;OL&gt;
&lt;LI&gt;StatementText="create procedure testproc&amp;amp;#x0D;&amp;amp;#x0A;as&amp;amp;#x0D;&amp;amp;#x0A;begin&amp;amp;#x0D;&amp;amp;#x0A;&amp;nbsp;&amp;nbsp;&amp;nbsp; declare @spid int&amp;amp;#x0D;&amp;amp;#x0A;&amp;nbsp;&amp;nbsp;&amp;nbsp; set @spid = @@spid&amp;amp;#x0D;&amp;amp;#x0A;&amp;nbsp;&amp;nbsp; "&lt;BR&gt;StatementId="1"&lt;BR&gt;StatementType="ASSIGN" 
&lt;LI&gt;StatementText=" select count(*) from master.sys.sysprocesses where spid = @spid&amp;amp;#x0D;&amp;amp;#x0A;&amp;nbsp;&amp;nbsp; "&lt;BR&gt;StatementId="2"&lt;BR&gt;StatementType="SELECT" 
&lt;LI&gt;StatementText=" select count(*) from master.sys.syslockinfo where req_spid = @spid&amp;amp;#x0D;"&lt;BR&gt;StatementId="3"&lt;BR&gt;StatementType="SELECT"&lt;/LI&gt;&lt;/OL&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The sys.dm_exec_query_stats will contain two rows one for each query only. So when we join sys.dm_exec_query_stats with sys.dm_exec_query_plan you will get the same showplan for both rows and we need to aggregate information from the plan or identify the appropriate StmtSimple nodes to get the cost of each query. So I generate first artificial counters by sorting and counting the statment_start_offset value from sys.dm_exec_query_stats. The same is done for the StmtSimple nodes in the query plan by selecting those of type "SELECT" and sorting them by StatementId value. Now this relative sequence numbers can be used to join and get the costing attributes for each query.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The final query that contains the logic to match the query stats with the plan nodes is shown below:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;declare @top_n_plans int;&lt;BR&gt;set @top_n_plans = 25;&lt;BR&gt;with XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as sql)&lt;BR&gt;select top(@top_n_plans)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; qst.text as sql_text, qp.query_plan&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.statement_id&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.statement_text as select_statement&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qps2.statement_optimization_level&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qps2.statement_optimization_early_abort_reason&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select sum(ro.SubTreeCost.value(&lt;/FONT&gt;&lt;A href="mailto:N'@EstimatedTotalSubtreeCost'"&gt;&lt;FONT face="Courier New" color=#800080&gt;N'@EstimatedTotalSubtreeCost'&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Courier New" color=#800080&gt;, 'float'))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from qp.query_plan.nodes(&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N'//sql:Batch/sql:Statements/sql:StmtSimple/sql:QueryPlan[1]/sql:RelOp[1]'&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;) as ro(SubTreeCost)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) as Totalcost&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qps2.statement_sub_tree_cost&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.creation_time, qst.last_execution_time, qst.execution_count&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.total_elapsed_time, qst.last_elapsed_time, qst.min_elapsed_time, qst.max_elapsed_time&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.total_worker_time, qst.last_worker_time, qst.min_worker_time, qst.max_worker_time&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.total_physical_reads, qst.last_physical_reads&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, qst.min_physical_reads, qst.max_physical_reads&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.total_logical_writes, qst.last_logical_writes&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.min_logical_writes, qst.max_logical_writes&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.total_logical_reads, qst.last_logical_reads&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.min_logical_reads, qst.max_logical_reads&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT face="Courier New" color=#800080&gt;, qst.total_clr_time, qst.last_clr_time&lt;/FONT&gt;&lt;FONT face="Courier New" color=#800080&gt;, qst.min_clr_time, qst.max_clr_time&lt;BR&gt;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qst.sql_handle, qst.plan_handle&lt;BR&gt;&amp;nbsp; from (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select *&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , substring(st.text, (qs.statement_start_offset/2)+1&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , ((case qs.statement_end_offset&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when -1 then datalength(st.text)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else qs.statement_end_offset&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end - qs.statement_start_offset)/2) + 1) as statement_text&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , ROW_NUMBER() OVER(PARTITION BY qs.plan_handle&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ORDER BY qs.statement_start_offset) as statement_id&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from sys.dm_exec_query_stats as qs&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cross apply sys.dm_exec_sql_text(qs.sql_handle) as st&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) as qst&lt;BR&gt;&amp;nbsp;cross apply sys.dm_exec_query_plan (qst.plan_handle) as qp&lt;BR&gt;&amp;nbsp;cross apply (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- Since sys.dm_exec_query_stats doesn't have statement id,&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- we just sort the actual statement id&amp;nbsp;from showplan for&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-- SELECT statements and join them with similar sequence number generated based&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- on the statement start offset in sys.dm_exec_query_stats.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- This allows us to match the row from showplan with that of the query stats.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- This is a problem for batches containing multiple SELECT statements&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- and hence this solution.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select ROW_NUMBER() OVER(ORDER BY qps1.statement_id) as rel_statement_id&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qps1.statement_optimization_level, qps1.statement_sub_tree_cost&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , qps1.statement_optimization_early_abort_reason&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select sel.StmtSimple.value(&lt;/FONT&gt;&lt;A href="mailto:'@StatementId'"&gt;&lt;FONT face="Courier New" color=#800080&gt;'@StatementId'&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Courier New" color=#800080&gt;, 'int')&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , sel.StmtSimple.value(&lt;/FONT&gt;&lt;A href="mailto:'@StatementSubTreeCost'"&gt;&lt;FONT face="Courier New" color=#800080&gt;'@StatementSubTreeCost'&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Courier New" color=#800080&gt;, 'float'&lt;/FONT&gt;&lt;FONT face="Courier New" color=#800080&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , sel.StmtSimple.value(&lt;/FONT&gt;&lt;A href="mailto:'@StatementOptmLevel'"&gt;&lt;FONT face="Courier New" color=#800080&gt;'@StatementOptmLevel'&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Courier New" color=#800080&gt;&lt;FONT face="Times New Roman" color=#000000&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#800080&gt;, 'varchar(30)')&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , sel.StmtSimple.value(&lt;/FONT&gt;&lt;A href="mailto:'@StatementOptmEarlyAbortReason'"&gt;&lt;FONT face="Courier New" color=#800080&gt;'@StatementOptmEarlyAbortReason'&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Courier New" color=#800080&gt;, 'varchar(30)')&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from qp.query_plan.nodes(&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N'//sql:Batch/sql:Statements/sql:StmtSimple[@StatementType = "SELECT"]'&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) as sel(StmtSimple)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) as qps1(statement_id,&amp;nbsp;statement_sub_tree_cost&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New" color=#800080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , statement_optimization_level, statement_optimization_early_abort_reason)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) as qps2&lt;BR&gt;&amp;nbsp;where qps2.rel_statement_id = qst.statement_id&lt;BR&gt;&amp;nbsp;--&amp;nbsp; and qst.text like ... /* can be used to filter only particular statemetns */&lt;BR&gt;&amp;nbsp;order by Totalcost desc, qst.plan_handle, qst.statement_id;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;BR&gt;Lastly, let me highlight the new relational, TSQL and Xquery features of SQL Server 2005 as used in the query.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;UL&gt;
&lt;LI&gt;TOP clause - Support for variables or expressions in the TOP clause 
&lt;LI&gt;APPLY operator - Used to join table against table-valued function in the query 
&lt;LI&gt;ROW_NUMBER analytic function - To generate sequence numbers based on a particular order and optionally partition the rows into different groups 
&lt;LI&gt;Xquery nodes method - To get the matching nodes based on a XPath expression for each instance of a query plan 
&lt;LI&gt;Xquery value method - To get a particular Xml attribute as a typed column 
&lt;LI&gt;WITH XMLNAMESPACES - To use namespace prefix in XPath expressions easily in a query&lt;/LI&gt;&lt;/UL&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;So run the query and enjoy the output / richness of metadata that SQL Server 2005 exposes. The Books Online topics and the MSDN links of the various features used in the query is below for convenience sake:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/ms189463(en-US,SQL.90).aspx"&gt;TOP (Transact-SQL)&amp;nbsp;&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/da983c0a-06c5-4cf8-a6a4-7f9d66f34f2c.htm 
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/ms177634(en-US,SQL.90).aspx"&gt;FROM (Transact-SQL)&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/36b19e68-94f6-4539-aeb1-79f5312e4263.htm 
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/ms186734(en-US,SQL.90).aspx"&gt;ROW_NUMBER (Transact-SQL)&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/82fa9016-77db-4b42-b4c8-df6095b81906.htm 
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/ms189461(en-US,SQL.90).aspx"&gt;OVER Clause (Transact-SQL)&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/ddcef3a6-0341-43e0-ae73-630484b7b398.htm 
&lt;LI&gt;&lt;A href="http://lab.msdn.microsoft.com/searchbeta/Redirect.aspx?title=sys.dm_exec_query_stats&amp;amp;url=http://msdn2.microsoft.com/en-us/library/ms189741.aspx"&gt;sys.dm_exec_query_stats&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/eb7b58b8-3508-4114-97c2-d877bcb12964.htm 
&lt;LI&gt;&lt;A href="http://lab.msdn.microsoft.com/searchbeta/Redirect.aspx?title=sys.dm_exec_sql_text&amp;amp;url=http://msdn2.microsoft.com/en-us/library/ms181929.aspx"&gt;sys.dm_exec_sql_text&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/61b8ad6a-bf80-490c-92db-58dfdff22a24.htm 
&lt;LI&gt;&lt;A href="http://lab.msdn.microsoft.com/searchbeta/Redirect.aspx?title=sys.dm_exec_query_plan&amp;amp;url=http://msdn2.microsoft.com/en-us/library/ms189747.aspx"&gt;sys.dm_exec_query_plan&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/e26f0867-9be3-4b2e-969e-7f2840230770.htm 
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/ms189298.aspx"&gt;XML Showplans&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/udb9/html/8f8fa597-1c57-496f-84cc-275c2b80fd8f.htm 
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/ms177400.aspx"&gt;Adding Namespaces Using WITH XMLNAMESPACES&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/udb9/html/2189cb5e-4460-46c5-a254-20c833ebbfec.htm 
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/ms177607(en-US,SQL.90).aspx"&gt;WITH XMLNAMESPACES (Transact-SQL)&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/3b32662b-566f-454d-b7ca-e247002a9a0b.htm 
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/ms188282.aspx"&gt;nodes() Method (xml Data Type)&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/udb9/html/7267fe1b-2e34-4213-8bbf-1c953822446c.htm 
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/ms178030.aspx"&gt;value() Method (xml Data Type)&lt;/A&gt; ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/udb9/html/298a7361-dc9a-4902-9b1e-49a093cd831d.htm&lt;BR&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;DIV&gt;--&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;Umachandar Jayachandran&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=477613" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqltips/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.msdn.com/sqltips/archive/tags/Dynamic+Management+View/default.aspx">Dynamic Management View</category></item><item><title>Determining optimal MAXDOP setting from TSQL in SQL Server 2005</title><link>http://blogs.msdn.com/sqltips/archive/2005/09/14/466387.aspx</link><pubDate>Wed, 14 Sep 2005 22:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:466387</guid><dc:creator>SQL Server Engine Team</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/sqltips/comments/466387.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqltips/commentrss.aspx?PostID=466387</wfw:commentRss><wfw:comment>http://blogs.msdn.com/sqltips/rsscomments.aspx?PostID=466387</wfw:comment><description>&lt;DIV&gt;
&lt;DIV&gt;For optimal performance of multi-processor installations, we recommend that the MAXDOP setting remain equal to the number of physical processors that are being used. For example, if the system is configured for two physical processors and four logical processors, MAXDOP should be set to 2. This is documented in the KB article:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;A href="http://support.microsoft.com/default.aspx/kb/322385"&gt;http://support.microsoft.com/default.aspx/kb/322385&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;But there is no easy way to determine the number of physical processors in case of hyper-threaded CPUs for example from TSQL itself. Often you have to resort to using OS utilities or write small program using&amp;nbsp;Win32 API&amp;nbsp; to determine the logical processors in a hyper-threaded configuration or&amp;nbsp;look at&amp;nbsp;the BIOS or processor type.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;In SQL Server 2005, there are set of views and table-valued functions that fall under the umbrella of Dynamic Management Views which expose lot of information about SQL Server, memory structures, SQLOS information and so on. More details can be obtained from the "&lt;SPAN id=nsrTitle&gt;Dynamic Management Views and Functions&lt;/SPAN&gt; " topic in Books Online:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/cf893ecb-0bf6-4cbf-ac00-8a1099e405b1.htm&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;You can now derive the logical processors information from sys.dm_os_sys_info DMV in SQL Server 2005 easily.&amp;nbsp;For example, the query below gives the&amp;nbsp;optimal MAXDOP setting taking into account&amp;nbsp;number of physical processors.&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;FONT face="Courier New"&gt;select case&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when cpu_count / hyperthread_ratio &amp;gt; 8 then 8&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else cpu_count / hyperthread_ratio&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end as optimal_maxdop_setting&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face="Courier New"&gt;from sys.dm_os_sys_info;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;This view also contains other interesting information like physical memory of the system, virtual memory available for processes, and number of schedulers. I will post more tips about the various interesting DMVs in SQL Server 2005. If you want to know about any particular area feel free to post a comment and I will post something on that.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;[Modified: 20060517]&lt;/DIV&gt;
&lt;DIV&gt;Recently, I came across a limitation in this system view. The hyperthread_ratio column is &amp;gt; 0 for the multi-core systems too. So there is no way to differentiate between a system with multi-core and hyperthreaded CPUs using the DMV. And since in the case of multi-core processor based systems, the MAXDOP value can be set to the number of CPUs the usefulness of the query is limited. The sure way to know the effect of MAXDOP setting is to test against your workload that involves parallel queries/operations.&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=466387" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqltips/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.msdn.com/sqltips/archive/tags/Best+Practices/default.aspx">Best Practices</category><category domain="http://blogs.msdn.com/sqltips/archive/tags/Dynamic+Management+View/default.aspx">Dynamic Management View</category></item></channel></rss>