<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.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>Louis Davidson : Dynamic Management Objects</title><link>http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management+Objects/default.aspx</link><description>Tags: Dynamic Management Objects</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>2008: Rebuilding a Heap</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2008/02/26/2008-rebuilding-a-heap.aspx</link><pubDate>Wed, 27 Feb 2008 04:10:24 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:5295</guid><dc:creator>drsql</dc:creator><slash:comments>7</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/5295.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=5295</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=5295</wfw:comment><description>&lt;p&gt;In 2005, rebuilding a table that was a heap (no clustered index) wasn't easy.&amp;nbsp; You could copy it to a different table, or you could add a clustered index and then drop it. &lt;/p&gt; &lt;p&gt;In 2008, this is a far easier thing to do.&amp;nbsp; They have added to the ALTER TABLE command a method to rebuild the table, which is the same as rebuilding the clustered index for a clustered table, but for a HEAP, it is the only way to go.&amp;nbsp; &lt;/p&gt; &lt;p&gt;In the following code sample, I create a heap, load it will "little data", then expand every row to much larger values.&amp;nbsp; The result is a little bit of fragmentation, but more than that, tons of forwarding pointers (when a row won't fit on the same heap page, it gets moved to a different page, but the pointer to the row does not change in the indexes.)&amp;nbsp; Rebuilding the heap is now really simple:&lt;/p&gt; &lt;p&gt;&lt;font color="#004080"&gt;create table heapDemo&lt;br&gt;(&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value varchar(1000)&lt;br&gt;)&lt;br&gt;GO&lt;br&gt;set nocount on&lt;br&gt;insert into heapDemo&lt;br&gt;select 'hi'&lt;br&gt;go 10000&lt;br&gt;--Expand the values to 500 times the size they were&lt;br&gt;update heapDemo&lt;br&gt;set value = replicate('hi',500)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;Now, check the stats of the table (using the index stats dmv, no less)&lt;/p&gt; &lt;p&gt;&lt;font color="#004080"&gt;select index_type_desc, fragment_count, page_count, forwarded_record_count&amp;nbsp; &lt;br&gt;from sys.dm_db_index_physical_stats(db_id(),default,default,default,'DETAILED')&lt;br&gt;where object_id = object_id('heapDemo')&lt;/font&gt; &lt;/p&gt; &lt;p&gt;This returns:&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="1"&gt;index_type_desc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fragment_count&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; page_count&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; forwarded_record_count&lt;br&gt;--------------------- -------------------- -------------------- ----------------------&lt;br&gt;HEAP&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; 6&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; 1443&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; 9961&lt;/font&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt;Now, you can rebuild the heap with the command:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#004080"&gt;alter table heapDemo rebuild&lt;/font&gt;&lt;/strong&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt;Check the values now:&lt;/p&gt; &lt;p&gt;&lt;font color="#004080"&gt;select index_type_desc, fragment_count, page_count, forwarded_record_count&lt;br&gt;from sys.dm_db_index_physical_stats(db_id(),default,default,default,'DETAILED')&lt;br&gt;where object_id = object_id('heapDemo')&lt;/font&gt; &lt;/p&gt; &lt;p&gt;This shows no that the forwarded_record_count is 0, which is the idea situation for your heap.&lt;/p&gt;&lt;font face="Courier New" size="1"&gt;index_type_desc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fragment_count&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; page_count&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; forwarded_record_count&lt;br&gt;--------------------- -------------------- -------------------- ----------------------&lt;br&gt;HEAP&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; 3&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; 1440&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; 0&lt;/font&gt;&lt;br&gt; &lt;p&gt;Nice new addition!&lt;/p&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=5295" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management+Objects/default.aspx">Dynamic Management Objects</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>sys.dm_db_index_operational_stats</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2007/08/26/sys-dm-db-index-operational-stats.aspx</link><pubDate>Sun, 26 Aug 2007 20:12:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:2341</guid><dc:creator>drsql</dc:creator><slash:comments>5</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/2341.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=2341</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=2341</wfw:comment><description>&lt;H3&gt;&amp;nbsp;&lt;/H3&gt;
&lt;P&gt;This object provides very useful stats on how many times an index has been used, locked, waited on, etc. An index in this context can mean several things: a clustered index, heap, index, or a partition of either of these. The grain of the function is down to the partition level, so if you are working with a table that is partitioned into five parts, it will return 5 rows (In the previous section, &lt;B&gt;sys.dm_db_index_usage_stats&lt;/B&gt; would have seen the object as only a single row) 
&lt;P&gt;This object will give you a deep feel for how indexes are being used, and just exactly how much the index is costing you. It does this in part by telling you how often the index is modified at the Leaf level or non-leaf level, as well as how often users waited on blocks associated with the object, which can mean SQL Server locks, or even hardware or I/O latches. 
&lt;P&gt;&lt;B&gt;Type&lt;/B&gt;: function 
&lt;P&gt;&lt;B&gt;Parameters:&lt;/B&gt; &lt;B&gt;database_id , object_id, index_id, partition_number&lt;/B&gt; (each parameter can be &lt;B&gt;NULL&lt;/B&gt; or &lt;B&gt;DEFAULT&lt;/B&gt; if you want to return all rows) 
&lt;P&gt;&lt;B&gt;Data:&lt;/B&gt; accumulating refreshed when server is restarted or (perhaps obviously) when the index is dropped and recreated. Statistics live on when the index is rebuild, reorganized, and even when it is disabled and rebuilt. 
&lt;P&gt;&lt;B&gt;Columns:&lt;/B&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;database_id&lt;/B&gt;, &lt;B&gt;object_id, index_id &lt;/B&gt;-identifies the index in question&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;partition_number &lt;/B&gt;- 1 for non-partitioned tables. For partitioned tables will be the 1 – based number of the partition.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;leaf_insert_count – &lt;/B&gt;the number of times a new row was added to the leaf of the index&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;leaf_delete_count – &lt;/B&gt;the number of times a row was deleted from the leaf&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;leaf_update_count – &lt;/B&gt;the number of changes to index keys for this index&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;leaf_ghost_count – &lt;/B&gt;the number of ghost records that have been marked as deleted but not cleaned up by SQL Server (&lt;A title=http://www.sql-server-performance.com/tips/glossary_p1.aspx href="http://www.sql-server-performance.com/tips/glossary_p1.aspx"&gt;http://www.sql-server-performance.com/tips/glossary_p1.aspx&lt;/A&gt;)&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;nonleaf_insert_count, nonleaf_delete_count, nonleaf_update_count – &lt;/B&gt;Same as the leaf page values, except for the b-tree index pages&lt;B&gt; &lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;leaf_allocation_count, nonleaf_allocation_count – &lt;/B&gt;The number of page allocated to the leaf and non-leaf pages of the index, respectively.&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;leaf_page_merge_count, nonleaf_page_merge_count – &lt;/B&gt;The&lt;B&gt; &lt;/B&gt;number of pages in the index that have been merged into a single page.&lt;B&gt; &lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;range_scan_count - &lt;/B&gt;number of times the index has been used in a range scan operator&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;singleton_lookup_count – &lt;/B&gt;number of times the index has been used to fetch a single row&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;forwarded_fetch_count – &lt;/B&gt;for a heap, shows the number of forward pointers have been used to resolve a query (&lt;A href="http://sqlblog.com/blogs/hugo_kornelis/archive/2006/11/03/The-table-scan-from-hell.aspx"&gt;http://sqlblog.com/blogs/hugo_kornelis/archive/2006/11/03/The-table-scan-from-hell.aspx&lt;/A&gt;)&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;lob_fetch_in_pages, lob_fetch_in_bytes – &lt;/B&gt;Quantifies the number of large object (varchar(max), varbinary(max), text, etc) have been retrieved using this index&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;lob_orphan_create_count, lob_orphan_insert_count – &lt;/B&gt;total number of large object pages orphaned by bulk operations &lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;row_overflow_fetch_in_pages , row_overflow_fetch_in_bytes – &lt;/B&gt;Quantifies the amount of data retrieved from row overflow pages for rows greater than one page in size&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;column_value_push_off_row_count, column_value_pull_in_row_count – &lt;/B&gt;Number of pages of large object or row overflow pages that have been moved by an in-row data operation&lt;B&gt; &lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;row_lock_count – &lt;/B&gt;number of row locks that have been requested against this&lt;B&gt; &lt;/B&gt;index&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;row_lock_wait_count &lt;/B&gt;– number of times a process has waited on a row lock against this index&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;row_lock_wait_in_ms &lt;/B&gt;– amount of time spent waiting on a row lock against this index&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;page_lock_count, page_lock_wait_count, page_lock_wait_in_ms &lt;/B&gt;– same as row_lock values at the page grain&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;index_lock_promotion_attempt_count, index_lock_promotion_count – &lt;/B&gt;number of times the lock grain for an operation using this index was attempted or granted to be escalated (like from row to page)&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;page_latch_wait_count , page_latch_wait_in_ms – &lt;/B&gt;number&lt;B&gt; &lt;/B&gt;of waits and time waited on the physical page of the object to have the latch removed &lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;page_io_latch_wait_count, page_io_latch_wait_in_ms - &lt;/B&gt;number&lt;B&gt; &lt;/B&gt;of waits and time waiting on and I/O operation on a physical page of the object to be completed &lt;B&gt;&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;This object is related to the &lt;B&gt;sys.dm_db_index_usage_stats&lt;/B&gt; in that they both provide information about how the index is used. This object, however, gives more detailed information about the inner workings of how the index is used at a physical level, whereas the usage stats is more of a feel for how it is used by the optimizer to satisfy the needs of certain queries. Use usage stats if you want counts of each usage, as each usage counts as 1. The operational stats object may have multiple values set for each type of activity recorded. (&lt;A href="http://blogs.msdn.com/sqlcat/archive/2005/12/12/502735.aspx"&gt;http://blogs.msdn.com/sqlcat/archive/2005/12/12/502735.aspx&lt;/A&gt;)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;B&gt;Examples:&lt;/B&gt; 
&lt;P&gt;Tables where the most latch contention is occurring 
&lt;P&gt;select object_schema_name(ddios.object_id) + '.' + object_name(ddios.object_id) as objectName,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; indexes.name, case when is_unique = 1 then 'UNIQUE ' else '' end + indexes.type_desc&amp;nbsp;as index_type,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; page_latch_wait_count , page_io_latch_wait_count&lt;BR&gt;from&amp;nbsp; &lt;B&gt;sys.dm_db_index_operational_stats(db_id(),null,null,null)&lt;/B&gt; as ddios&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; join sys.indexes&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; on indexes.object_id = ddios.object_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;&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; and indexes.index_id = ddios.index_id&lt;BR&gt;order by page_latch_wait_count + page_io_latch_wait_count desc&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;Note:&amp;nbsp; This is part of an ongoing project to write a book about all of the dynamic management views for &lt;/FONT&gt;&lt;A href="http://www.red-gate.com/" target=_blank&gt;&lt;FONT face="Courier New" color=#02469b&gt;Red-Gate&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Courier New"&gt;.&amp;nbsp;It will be freely distributable once complete as an ebook.&amp;nbsp;Any examples, suggestions, corrections are desired and will certainly be mentioned in the final book.&amp;nbsp; Also, I will begin maintaining the following web page once the book is closer to completion: &lt;/FONT&gt;&lt;A href="http://drsql.org/dmvbook.aspx"&gt;&lt;FONT face="Courier New" color=#02469b&gt;http://drsql.org/dmvbook.aspx&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Courier New"&gt;. &lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=2341" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management+Objects/default.aspx">Dynamic Management Objects</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>sys.dm_exec_query_optimizer_info</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2007/08/06/sys-dm-exec-query-optimizer-info.aspx</link><pubDate>Tue, 07 Aug 2007 00:40:55 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:2141</guid><dc:creator>drsql</dc:creator><slash:comments>1</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/2141.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=2141</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=2141</wfw:comment><description>&lt;p&gt;Information about how queries have been optimized since the server has been restarted. Note that counters are only affected when there is some sort of optimization event, not on every query. (reference: &lt;a href="http://sqlserver-qa.net/blogs/perftune/archive/2007/05/11/get-statistics-on-query-plan-optimizer-execution.aspx"&gt;http://sqlserver-qa.net/blogs/perftune/archive/2007/05/11/get-statistics-on-query-plan-optimizer-execution.aspx&lt;/a&gt; )&lt;/p&gt; &lt;p&gt;&lt;b&gt;Type&lt;/b&gt;: View &lt;p&gt;&lt;b&gt;Data&lt;/b&gt;: Accumulating reset at restart &lt;p&gt;&lt;b&gt;Columns:&lt;/b&gt; &lt;ul&gt; &lt;li&gt;&lt;b&gt;counter&lt;/b&gt; - Name of the query&lt;/li&gt; &lt;li&gt;&lt;b&gt;occurrence – &lt;/b&gt;Number of times&lt;b&gt; &lt;/b&gt;the counter was recorded to&lt;b&gt;&lt;/b&gt;&lt;/li&gt; &lt;li&gt;&lt;b&gt;value – &lt;/b&gt;May or may not have some value, but is typically an average of the values that were recorded when the counter was written to (for a complete list of counters, check the books online documentation on sys.dm_exec_query_optimizer_info (1))&lt;b&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;b&gt;Example:&lt;/b&gt; &lt;p&gt;As an example, on a low use server, I restarted the server and executed: &lt;p&gt;select counter,occurrence, value&lt;br&gt;from sys.dm_exec_query_optimizer_info  &lt;p&gt;You will get values like: &lt;p&gt;&lt;font face="Courier New" size="2"&gt;counter&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; occurrence&amp;nbsp;&amp;nbsp;&amp;nbsp; value&lt;br&gt;----------------- ------------- -------------------- &lt;br&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;optimizations&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&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;1&lt;br&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;elapsed time&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.0235776097702821&lt;br&gt;final cost&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4.1957E-05&lt;/font&gt; &lt;p&gt;This tells you the number of statements that have been optimized and a plan created (the same value is for all three of the displayed counters), the average elapsed time spent compiling in the value column for the elapsed time row, and finally, the average final cost in the final cost row. Using these counters and some of the others you will discover will help you to determine how often statements ae being compiled. &lt;p&gt;Execute it again, it will give you the same values (assuming you are the only user, of course.) Now, execute the same query, this time making it uppercase, forcing another complication, since plans must match in every way: &lt;p&gt;SELECT COUNTER, OCCURRENCE, VALUE&lt;br&gt;FROM SYS.DM_EXEC_QUERY_OPTIMIZER_INFO  &lt;p&gt;You will see that the occurrences have increased, and there may be some difference in the average time it took: &lt;p&gt;&lt;font face="Courier New" size="2"&gt;counter&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; occurrence&amp;nbsp;&amp;nbsp;&amp;nbsp; value&lt;br&gt;----------------- ------------- -------------------- &lt;br&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;optimizations&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&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;1&lt;br&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;elapsed time&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.020978588737036&lt;br&gt;final cost&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4.1957E-05&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;---------------------------------------&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;Note:&amp;nbsp; This is part of an ongoing project to write a book about all of the dynamic management views for &lt;a href="http://www.red-gate.com" target="_blank"&gt;Red-Gate&lt;/a&gt;.&amp;nbsp;It will be freely distributable once complete as an ebook.&amp;nbsp;Any examples, suggestions, corrections are desired and will certainly be mentioned in the final book.&amp;nbsp; Also, I will begin maintaining the following web page once the book is closer to completion: &lt;a href="http://drsql.org/dmvbook.aspx"&gt;http://drsql.org/dmvbook.aspx&lt;/a&gt;. &lt;/font&gt;&lt;/p&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=2141" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management+Objects/default.aspx">Dynamic Management Objects</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>sys.dm_io_virtual_file_stats</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2007/07/27/sys-dm-io-virtual-file-stats.aspx</link><pubDate>Sat, 28 Jul 2007 01:26:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1960</guid><dc:creator>drsql</dc:creator><slash:comments>12</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/1960.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=1960</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=1960</wfw:comment><description>&lt;P&gt;Excellent dmv that shows, for each file that SQL Server uses for the databases, stats on how frequently the file has been used by the database. This is one of the primary dynamic management views I use almost daily (well, not usually when I am on vacation, but even sometimes then!)&amp;nbsp; The file can be any file used in the database, including the log or full text files. 
&lt;P&gt;&lt;B&gt;Type:&lt;/B&gt; Function 
&lt;P&gt;&lt;B&gt;Parameters: &lt;/B&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;database_id – &lt;/B&gt;key of the database, retrieved from sys.databases&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;file_id - &lt;/B&gt;key of a file in a database. Can be retrieved from sys.database_files if you are working in the context of a database, or sys.master_files will give you all files in all databases&lt;B&gt;&lt;/B&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;B&gt;Columns:&lt;/B&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;database_id, file_id&lt;/B&gt; – same as the parameter descriptions&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;sample_ms&lt;/B&gt; – the number of milliseconds that have passed since the values for sys.dm_io_virtual_file_stats were reset the only way to reset the values is to restart the server.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;num_of_reads&lt;/B&gt; – number of individual read operations that were issued to the file. Note that this is physical reads, not logical reads. Logical reads would not be registered. &lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;num_of_bytes_read&lt;/B&gt; – the number of bytes that were read, as opposed to the number of reads. The size of a read is not a constant value that can be calculated by the number of reads.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;Io_stall_read_ms&lt;/B&gt; – total time user processes waited for IO. Note that this number can be much greater than the sample_ms. If 10 processes are trying to use the file simultaneously, but the disk is only able to server 1, then you might get 9 seconds waiting over a 10 second time period.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;num_of_writes , num_of_bytes_written, io_stall_write_ms&lt;/B&gt; - the same as the read values, except for writes.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;io_stall&lt;/B&gt; – sum of io_stall_write_ms and io_stall_read_ms&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;size_on_disk_bytes&lt;/B&gt; – the size of the file in bytes &lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;file_handle&lt;/B&gt; – the Windows file handle of the file (Books Online)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;B&gt;Example:&lt;/B&gt; 
&lt;P&gt;For all databases, get vital stats on how busy the file has been, since the last restart: 
&lt;P&gt;&lt;FONT face="Courier New"&gt;select db_name(mf.database_id) as databaseName, mf.physical_name,&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;num_of_reads, num_of_bytes_read, io_stall_read_ms, num_of_writes, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;num_of_bytes_written, io_stall_write_ms, io_stall,size_on_disk_bytes&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;from sys.dm_io_virtual_file_stats(null,null) as divfs&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;join sys.master_files as mf&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; &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;on mf.database_id = divfs.database_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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;and mf.file_id = divfs.file_id&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=1960" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management+Objects/default.aspx">Dynamic Management Objects</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>sys.dm_db_index_usage_stats</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2007/07/22/sys-dm-db-index-usage-stats.aspx</link><pubDate>Mon, 23 Jul 2007 02:45:12 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1883</guid><dc:creator>drsql</dc:creator><slash:comments>9</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/1883.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=1883</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=1883</wfw:comment><description>&lt;p&gt;This object gives statistics on how an index has been used to resolve queries. Most importantly it tells you the number of times a query was used to find a single row (&lt;b&gt;user_seeks&lt;/b&gt;), a range of values, or to resolve a non-unique query (&lt;b&gt;user_scans&lt;/b&gt; ), if it has been used to resolve a bookmark lookup (user_lookups) and how many changes to the index (&lt;b&gt;user_updates&lt;/b&gt;. Note that &lt;b&gt;sys.dm_db_index_operational_stats&lt;/b&gt; will give the details of how it has been modified.)  &lt;p&gt;It returns all indexes (including heaps and the clustered index) from the entire server for each index that has been used, though you will usually only want to use it for one database since you will have to look up the name of the index in &lt;b&gt;sys.indexes&lt;/b&gt;. There will not be a row in &lt;b&gt;sys.dm_db_index_usage_stats&lt;/b&gt; unless the index has been used since creation or since SQL Server has been restarted.  &lt;p&gt;&lt;b&gt;Type: &lt;/b&gt;view  &lt;p&gt;&lt;b&gt;Data:&lt;/b&gt; accumulating, refreshed when server is restarted or (perhaps obviously) when the index is dropped and recreated. Statistics live on when the index is rebuild, reorganized, and even when it is disabled and rebuilt.  &lt;p&gt;&lt;b&gt;Columns:&lt;/b&gt;  &lt;ul&gt; &lt;li&gt;&lt;b&gt;database_id&lt;/b&gt; – primary key of the database&lt;b&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;object_id&lt;/b&gt; - the object_id of the table the index belongs to &lt;b&gt;&lt;/b&gt; &lt;li&gt;&lt;b&gt;index_id &lt;/b&gt;- the primary key of the index&lt;b&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;user_seeks&lt;/b&gt; – the number of times the index has been used in a user query in a seek operation (one specific row)&lt;b&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;user_scans&lt;/b&gt; – the number of times the index has been used by scanning the leaf pages of the index for data&lt;b&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;user_lookups&lt;/b&gt; – for clustered indexes only, this is the number of times the index has been used in a "bookmark lookup" to fetch the full row. This is because non-clustered indexes use the clustered indexes key as the pointer to the base row.&lt;b&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;user_updates&lt;/b&gt; – The number of times the index has been modified due to a change in the table's data.&lt;b&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;last_user_seek&lt;/b&gt; – The date and time of the last user seek operation&lt;b&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;last_user_scan&lt;/b&gt; – The date and time of the last user scan operation&lt;b&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;last_user_lookup&lt;/b&gt; – The date and time of the last user lookup operation&lt;b&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;last_user_update&lt;/b&gt; – The date and time of the last user update operation&lt;b&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;system_seeks, system_scans, system_lookups, system_updates, last_system_seek, last_system_scan, last_system_lookup, last_system_update - &lt;/b&gt;Same as the user query columns, but records when the index is used for a system operation, such as automatic statistics operations.&lt;b&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This is one of the most interesting views that I often use in performance tuning. It gives you something that no previous version of SQL Server did (at least in an easy to discover manner for the "average" dba, that I know of): The ability to tell when indexes are NOT being used. It is easy to see when an index is being used by a query by simply looking at the plan. But now, using this dynamic management view, you can see over time what indexes are used, not used, and probably more importantly, updated many many times and never being used.  &lt;p&gt;&lt;b&gt;Examples:&lt;/b&gt;  &lt;p&gt;Create table, do a few queries in tempdb.&amp;nbsp; Table and full code will be in final book.  &lt;p&gt;--returns all indexes for a database and their stats.&lt;br&gt;--Rows with no usage since the last restart will be null  &lt;p&gt;select object_schema_name(indexes.object_id) + '.' + object_name(indexes.object_id) as objectName,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;indexes.name, case when is_unique = 1 then 'UNIQUE ' else '' end + indexes.type_desc, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ddius.user_seeks, ddius.user_scans, ddius.user_lookups, ddius.user_updates&lt;br&gt;from sys.indexes&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; left outer join sys&lt;b&gt;.dm_db_index_usage_stats&lt;/b&gt; ddius&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; on indexes.object_id = ddius.object_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;&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; and indexes.index_id = ddius.index_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;&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; and ddius.database_id = db_id()&lt;br&gt;order by ddius.user_seeks + ddius.user_scans + ddius.user_lookups desc&lt;/p&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=1883" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management+Objects/default.aspx">Dynamic Management Objects</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>sys.dm_db_file_space_usage</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2007/07/14/sys-dm-db-file-space-usage.aspx</link><pubDate>Sat, 14 Jul 2007 19:35:20 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1730</guid><dc:creator>drsql</dc:creator><slash:comments>4</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/1730.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=1730</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=1730</wfw:comment><description>&lt;p&gt;Give space usage of objects in tempdb (most likely this will be extended to more than just tempdb in a future edition of SQL Server.) Can be used to see how and why space is being used in Tempdb, on a file by file basis. &lt;p&gt;&lt;b&gt;Type: &lt;/b&gt;View &lt;p&gt;&lt;b&gt;Data:&lt;/b&gt; temporal, reflects the current state of the file usage &lt;p&gt;&lt;b&gt;Columns:&lt;/b&gt; &lt;ul&gt; &lt;li&gt;&lt;b&gt;database_id&lt;/b&gt; – identifies the database (relates to sys.databases)&amp;nbsp;(NOTE: only includes tempdb in 2005)&lt;/li&gt; &lt;li&gt;&lt;b&gt;file_id&lt;/b&gt; – the file identifier (relates to sys.database_files)&lt;/li&gt; &lt;li&gt;&lt;b&gt;unallocated_extent_page_count &lt;/b&gt;– Total number of pages that are located on unallocated extents (8 contiguous 8K pages) that are reserved in the file but not currently allocated to objects. Note that unused pages on extents that have any active data on them will not be reflected in the total.&lt;/li&gt; &lt;li&gt;&lt;b&gt;version_store_reserved_page_count – &lt;/b&gt;Number of pages that are reserved to support snapshot isolation transactions.&lt;/li&gt; &lt;li&gt;&lt;b&gt;user_object_reserved_page_count - &lt;/b&gt;Number of pages reserved to user tables&lt;b&gt;&lt;/b&gt;&lt;/li&gt; &lt;li&gt;&lt;b&gt;internal_object_reserved_page_count&lt;/b&gt; &lt;b&gt;-&lt;/b&gt;&lt;b&gt; &lt;/b&gt;Number of pages reserved to internal objects, such as work tables that SQL Server creates to hold intermediate results&lt;/li&gt; &lt;li&gt;&lt;b&gt;mixed_extent_page_count&lt;/b&gt; – Number of extents that have pages of multiple types (user objects, version store, or internal objects, Index Allocation Map (IAM) pages, etc.)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;b&gt;Example:&lt;/b&gt; &lt;p&gt;The following query will show the number of pages allocated to each file in your tempdb, and how much space is allocated to the various purposes, or unallocated. &lt;p&gt;select mf.physical_name, mf.size as entire_file_page_count,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dfsu.unallocated_extent_page_count,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dfsu.user_object_reserved_page_count, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dfsu.internal_object_reserved_page_count,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dfsu.mixed_extent_page_count&lt;br&gt;from sys.dm_db_file_space_usage dfsu&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join sys.master_files as mf&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; on mf.database_id = dfsu.database_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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and mf.file_id = dfsu.file_id&lt;/p&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=1730" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management+Objects/default.aspx">Dynamic Management Objects</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>sys.dm_db_partition_stats</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2007/07/11/sys-dm-db-partition-stats.aspx</link><pubDate>Thu, 12 Jul 2007 01:41:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1677</guid><dc:creator>drsql</dc:creator><slash:comments>3</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/1677.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=1677</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=1677</wfw:comment><description>&lt;P&gt;For the current database, gives you space oriented statistics for each partition of indexes (even if you only have one partion), like row count, page counts, etc. Resembles the sysindexes in previous versions of SQL Server, with more information.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Type:&lt;/B&gt; view&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Data:&lt;/B&gt; &lt;SPAN style="FONT-SIZE:11pt;LINE-HEIGHT:115%;FONT-FAMILY:'Calibri','sans-serif';mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:'Times New Roman';mso-bidi-theme-font:minor-bidi;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes;"&gt;accumulating, refreshed at server restart&lt;/SPAN&gt; 
&lt;P&gt;&lt;STRONG&gt;Scope:&lt;/STRONG&gt; Reset on server restart (or object/partition drop and recreate) 
&lt;P&gt;&lt;B&gt;Columns:&lt;/B&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;partition_id &lt;/B&gt;- numeric identifier of the partition (relates to sys.partitons) 
&lt;LI&gt;&lt;B&gt;object_id &lt;/B&gt;- the object_id of the object that the partition belongs to 
&lt;LI&gt;&lt;B&gt;index_id&lt;/B&gt; - identifies the index on the table. 0 = Heap 
&lt;LI&gt;&lt;B&gt;partition_number &lt;/B&gt;- 1 for non-partitioned tables. For partitioned tables will be the 1 – based number of the partition. 
&lt;LI&gt;&lt;B&gt;in_row_data_page_count &lt;/B&gt;- the number of pages being used for data of the object. Can be the leaf pages of an index or the data pages of a clustered table or heap 
&lt;LI&gt;&lt;B&gt;in_row_used_page_count &lt;/B&gt;- Includes all pages in use for the object, including non-leaf index and index allocation map pages. 
&lt;LI&gt;&lt;B&gt;in_row_reserved_page_count &lt;/B&gt;- Includes all pages in use plus any pages reserved for the object, even if the pages are not currently in use. 
&lt;LI&gt;&lt;B&gt;lob_used_page_count - &lt;/B&gt;Count of pages in use for the object to store out-of-row values such as varchar(max), varbinary(max), etc.&lt;B&gt;&lt;/B&gt; 
&lt;LI&gt;&lt;B&gt;lob_reserved_page_count&lt;/B&gt; – Count of out of the row pages including any that are reserved but not in use. 
&lt;LI&gt;&lt;B&gt;row_overflow_used_page_count - &lt;/B&gt;Count of&lt;B&gt; &lt;/B&gt;pages that&lt;B&gt; &lt;/B&gt;are in use for storing overflow data for rows that are larger than will fit on a single ~8K page&lt;B&gt;&lt;/B&gt; 
&lt;LI&gt;&lt;B&gt;row_overflow_reserved_page_count &lt;/B&gt;- Count of overlow pages that includes any pages that are reserved but not in use 
&lt;LI&gt;&lt;B&gt;used_page_count &lt;/B&gt;- Total number of pages in use in the partiton for any reason 
&lt;LI&gt;&lt;B&gt;reserved_page_count &lt;/B&gt;- Total number of pages in use or reserved in the partiton for any reason 
&lt;LI&gt;&lt;B&gt;row_count&lt;/B&gt; – The number of rows in the table&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Examples:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Get rowcount of tables. Note that I grouped on the object_id, because for a partitioned table, you need to add all of the rows in all partitions. 
&lt;P&gt;select object_name(dm_db_partition_stats.object_id), &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum(dm_db_partition_stats.row_count) as row_count&lt;BR&gt;from sys.dm_db_partition_stats&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; join sys.indexes&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;on indexes.object_id = dm_db_partition_stats.object_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;&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;and indexes.index_id = dm_db_partition_stats.index_id&lt;BR&gt;where indexes.type_desc in ('CLUSTERED','HEAP')&lt;BR&gt;group by dm_db_partition_stats.object_id&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Other planned examples include a sample partition to show the rowcounts/usage, and summations of some of the other values to give a meaningful data other than rowcount.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class=wlWriterSmartContent id=0767317B-992E-4b12-91E0-4F059A8CECA8:c8bfc5c1-2b50-4241-8628-724591375151 style="PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;FLOAT:none;PADDING-BOTTOM:0px;MARGIN:0px;PADDING-TOP:0px;"&gt;SQLBlog Tags: &lt;A href="http://sqlblog.com/blogs/Louis_davidson/archive/tags/SQL%20Server/default.aspx" rel=tag&gt;SQL Server&lt;/A&gt;, &lt;A href="http://sqlblog.com/blogs/Louis_davidson/archive/tags/Dynamic%20Management%20Objects/default.aspx" rel=tag&gt;Dynamic Management Objects&lt;/A&gt;, &lt;A href="http://sqlblog.com/blogs/Louis_davidson/archive/tags/T-SQL/default.aspx" rel=tag&gt;T-SQL&lt;/A&gt;&lt;/DIV&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=1677" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management+Objects/default.aspx">Dynamic Management Objects</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>Blogging the DMV's</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2007/07/10/blogging-the-dmv-s.aspx</link><pubDate>Tue, 10 Jul 2007 04:14:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1639</guid><dc:creator>drsql</dc:creator><slash:comments>4</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/1639.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=1639</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=1639</wfw:comment><description>&lt;P&gt;Well, I am working on a project that is going to be a book on dynamic management views (and functions, but DMF is an interesting acronym, and objects, as in DMO, has a well known other meaning.&amp;nbsp; What I will post will be one object in the following format:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Name of object&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Type:&lt;/STRONG&gt; Function or View&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Parameters: &lt;/STRONG&gt;If it is a function&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Scope: &lt;/STRONG&gt;Really denotes how long the data's life is for.&amp;nbsp; Many of the dynamic management functions are used to record some event, like an index being use for a query.&amp;nbsp; There is not usually (well, I haven't finished cataloging them, but so far there is never) any way to reset the values without rebooting the server.&amp;nbsp; There are tools to use to mitigate the issue, (like Tom Davidson's DMVStats tool that&amp;nbsp;Kalen mentions &lt;A href="http://sqlblog.com/blogs/kalen_delaney/archive/2007/06/29/check-it-out-tom-davidson-s-dmvstats-tool-is-now-available.aspx" target=_blank&gt;here&lt;/A&gt;,)&amp;nbsp;but the first time you look at the data in these objects it will be a bit confusing if you don't know how long the data has been gathered.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Columns: &lt;/STRONG&gt;A listing for all of the columns that are output by the DMV, including a description&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Example Usage: &lt;/STRONG&gt;A query or two regarding possible uses&lt;/P&gt;
&lt;P&gt;Then finally, there will be a section of the book that has&amp;nbsp;a list of ways you can use the DMV's to diagnose common things about your server.&lt;/P&gt;
&lt;P&gt;The book will be very reasonably priced (or not priced) and you will hear more about that over the next few weeks.&amp;nbsp; What I am asking of you (and you over there to the left) is&amp;nbsp;for your comments/likes, dislikes, and especially query ideas.&amp;nbsp; I will include your query in the book&amp;nbsp;(or coalesce it with others) and everyone who comments constructively will be mentioned in the acknowledgements of the book.&amp;nbsp; I will also include any links you might have to DMV related queries in the Bibliography (which already has 16 items in it from just getting started.)&lt;/P&gt;
&lt;P&gt;I will be posting these to my &lt;A title=http://sqlblog.com/blogs/louis_davidson/default.aspx href="http://sqlblog.com/blogs/louis_davidson/default.aspx"&gt;http://sqlblog.com/blogs/louis_davidson/default.aspx&lt;/A&gt;&amp;nbsp;site only, since comments there can be entered without a passport.&amp;nbsp; I will make mention of it on my &lt;A href="http://drsql.spaces.live.com/"&gt;http://drsql.spaces.live.com&lt;/A&gt;&amp;nbsp;blog and provide more loose commentary about the writing process.&amp;nbsp; &lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=1639" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management+Objects/default.aspx">Dynamic Management Objects</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>Automatic indexing is cool...plus something to tell you what indexes aren't used</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2006/10/12/automatic-indexing-is-cool-plus-something-to-tell-you-what-indexes-aren-t-used.aspx</link><pubDate>Thu, 12 Oct 2006 22:28:27 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:293</guid><dc:creator>drsql</dc:creator><slash:comments>0</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/293.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=293</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=293</wfw:comment><description>&lt;p&gt;Now, I will admit up front that I haven't technically tried out all of their bits and pieces of the following tool, but over the past week I have made a lot of use of some of the indexing suggestions by "hacking" out the code that generates the index create statements from the sys.dm_db_missing_index_group_stats dynamic management view.&amp;nbsp; Let me just say upfront: "Wow!"&amp;nbsp; I have seen some very wild index suggestions come from it, and today I took a few of the examples and applied them.&amp;nbsp;&amp;nbsp;We saw a 30-50% improvement over the test without the indexes.&lt;/p&gt; &lt;p&gt;The blog was: &lt;a href="http://blogs.msdn.com/queryoptteam/archive/2006/06/01/613516.aspx" target="_blank"&gt;Fun for the day - Automated Auto-Indexing!&lt;/a&gt; and was posted back in June!&amp;nbsp; I have been dying to try it out, but I am generally not one for building elaborate testing scenarios, so it has been a blog entry just circling waiting to see the light.&lt;/p&gt; &lt;p&gt;Well, over the last few days we have really started hammering on my companies product, preparing to ship it and one of the tools I used was their auto-indexing query that you can download from that blog entry.&amp;nbsp; It uses 3 dynamic management views that are awfully cool: sys.dm_db_missing_index_group_stats, sys.dm_db_missing_index_groups and&amp;nbsp;sys.dm_db_missing_index_details to build a set of actual create table statements (ok, a few other tables are involved, but still)&lt;/p&gt; &lt;p&gt;I am not promising you it will be the answer to all of your indexing problems, especially since it only considers what indexes it would have liked to have had to answer a query.&amp;nbsp; It doesn't have a clue what your read/write ratio is.&amp;nbsp; I hope to try out the full blown automatic index generation package with SQL Agent jobs to automatically tune my data warehouse and operation data stores in the future.&amp;nbsp; Any place with only reads (when not loading, of course) should be almost a no brainer...&lt;/p&gt; &lt;p&gt;So you add all of these indexes to improve performance, but as you know, indexes improve performance, but they also hurt write performance.&amp;nbsp; In this blog:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/sqlcat/archive/2006/02/13/531339.aspx"&gt;How can SQL Server 2005 help me evaluate and manage indexes?&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The Microsoft team with the only name longer than the name of my book (Microsoft SQL Server Development Customer Advisory Team) gives lots of interesting queries to assist with performance tuning. For example, this query:  &lt;p&gt;--- rarely used indexes appear first  &lt;p&gt;declare @dbid int  &lt;p&gt;select @dbid = db_id() &lt;br&gt;select objectname = object_name(s.object_id) &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , s.object_id &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , indexname = i.name &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , i.index_id &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , user_seeks&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, user_scans &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , user_lookups &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , user_updates &lt;br&gt;from sys.dm_db_index_usage_stats s&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join &amp;nbsp;sys.indexes i &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; on i.object_id = s.object_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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and i.index_id = s.index_id &lt;br&gt;where database_id = @dbid &lt;br&gt;and objectproperty(s.object_id , 'IsUserTable') = 1 &lt;br&gt;order by (user_seeks + user_scans + user_lookups + user_updates) asc &lt;/p&gt; &lt;p&gt;Lists how often indexes are used, from least to most. Obviously these are tools that we need to consider using when we tune a new system, but we will certainly want to really watch stuff like this during early days when a system hits production to look at trimming back indexes that are purely for performance that are never being used for such.&amp;nbsp; Stats like this are useless unless you have a totally full load and have gone through real life situations, unlike the previous, “what might have helped” queries from the automatic indexing stuff.  &lt;p&gt;SQL Server keeps getting better and better, and these sorts of thing are some of the primary evidence.&amp;nbsp; If you haven't started to look at the dynamic management views, you should.&amp;nbsp; If only to google them and check out what the blogs are saying about them.&amp;nbsp;  &lt;p&gt;Crossposted to &lt;a href="http://drsql.spaces.live.com"&gt;http://drsql.spaces.live.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=293" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management+Objects/default.aspx">Dynamic Management Objects</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category></item></channel></rss>