{"id":3958,"date":"2013-01-14T20:49:57","date_gmt":"2013-01-14T20:49:57","guid":{"rendered":"http:\/\/craftydba.com\/?p=3958"},"modified":"2017-10-08T17:54:18","modified_gmt":"2017-10-08T17:54:18","slug":"finding-table-info","status":"publish","type":"post","link":"https:\/\/craftydba.com\/?p=3958","title":{"rendered":"Finding Table Info"},"content":{"rendered":"<p><a href=\"https:\/\/craftydba.com\/wp-content\/uploads\/2013\/01\/info.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/craftydba.com\/wp-content\/uploads\/2013\/01\/info-150x150.png\" alt=\"\" title=\"database information\" width=\"150\" height=\"150\" class=\"alignleft size-thumbnail wp-image-3906\" srcset=\"https:\/\/craftydba.com\/wp-content\/uploads\/2013\/01\/info-150x150.png 150w, https:\/\/craftydba.com\/wp-content\/uploads\/2013\/01\/info.png 256w\" sizes=\"auto, (max-width: 150px) 100vw, 150px\" \/><\/a><br \/>\nJust the other day I was asked by a Business Line Manager about the usage patterns of tables in a database that I never seen before.  I was lucky that the version of the database was 2005 and Dynamic Management Views existed that stored the requirement information.<\/p>\n<p>Today, I am going to review a simple SELECT query that will retrieve the information that we want.<\/p>\n<p>The first requirement is to list the schema names that the user tables belong to.  We can obtain this information by looking at the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms176011.aspx\">sys.schemas<\/a> system view.<\/p>\n<p>The second requirement is to enumerate all the user tables to show their names and creation dates.  We can obtain this information by querying the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms190324.aspx\">sys.objects<\/a> system view.  We will want to filter the returned data set for only user tables (&#8216;U&#8217;).  Ordering the results by table name is nice feature.<\/p>\n<p>The third requirement is to display the row counts for all clustered indexes (id=1) or heaps (id=0).  This count is equal to the number of records in the table.  This information can be retrieved from the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms173760.aspx\">sys.indexes<\/a> system view.<\/p>\n<p>The fourth requirement is to display the number of updates, look ups, seeks, and scans that occurred against these base indexes.  Date time stamps associated with these actions will tell us table usage patterns.  The <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms188755.aspx\">sys.dm_db_index_usage_stats<\/a> Dynamic Management View (<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms188754.aspx\">DMV<\/a>) will supply us these numbers.<\/p>\n<p>The TSQL below will return the information that we want.<\/p>\n<pre class=\"lang:TSQL theme:familiar mark:1,2-3\" title=\"dynamic management view - index usage stats\">\r\n-- Which database to use.\r\nUSE [PUBS_DW]\r\nGO\r\n\r\n-- Counters are cleared every time SQL Service is re-started\r\nSELECT  \r\n\r\n    -- Table, index, row cnt, creation date\r\n    E.name as [schema_name],\r\n    O.Name as [table_name], \r\n    O.CrDate as [create_date],\r\n    I.Rows as [rows_in_table], \r\n    I.Name as [index_name],\r\n\r\n    -- How many?\r\n    S.user_updates, \r\n    S.user_lookups, \r\n    S.user_seeks, \r\n    S.user_scans,\r\n\r\n    -- When was it last\r\n    S.last_user_update, \r\n    S.last_user_lookup, \r\n    S.last_user_seek, \r\n    S.last_user_scan\r\nFROM \r\n    sys.schemas E \r\n    INNER JOIN sys.sysobjects O ON E.schema_id = O.uid\r\n    INNER JOIN sys.sysindexes I ON O.id = I.id\r\n    LEFT JOIN sys.dm_db_index_usage_stats S \r\n        ON S.index_id = I.indid and S.object_id = O.id\r\nWHERE  \r\n    -- User tables\r\n    O.type = 'U' AND \r\n\r\n    -- Heap = 0, Clustered = 1, > 1 = All others\r\n    I.IndId < 2 \r\n\r\n    -- Current database\r\n    AND S.database_id = DB_ID() \r\nORDER BY \r\n    O.Name\r\n\r\n<\/pre>\n<p>The following output was generated on a new data warehouse [PUBS_DW] that I created.  I will be reviewing that schema in the near future to demonstrate data warehousing design patterns.<\/p>\n<p><a href=\"https:\/\/craftydba.com\/wp-content\/uploads\/2013\/01\/dm-db-index-usage-stats.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/craftydba.com\/wp-content\/uploads\/2013\/01\/dm-db-index-usage-stats-1024x234.jpg\" alt=\"\" title=\"dm-db-index-usage-stats\" width=\"665\" height=\"151\" class=\"aligncenter size-large wp-image-3978\" srcset=\"https:\/\/craftydba.com\/wp-content\/uploads\/2013\/01\/dm-db-index-usage-stats-1024x234.jpg 1024w, https:\/\/craftydba.com\/wp-content\/uploads\/2013\/01\/dm-db-index-usage-stats-300x68.jpg 300w, https:\/\/craftydba.com\/wp-content\/uploads\/2013\/01\/dm-db-index-usage-stats.jpg 1470w\" sizes=\"auto, (max-width: 665px) 100vw, 665px\" \/><\/a><\/p>\n<p>In a nutshell, the TSQL statement above will tell you enough information to determine if a table is ACTIVE or INACTIVE.  Also, you can determine if the table is being updated and\/or queried.  <\/p>\n<p>Just remember, the counters for this DMV are reset every time the SQL Server Service is re-started.  Therefore, this query will return no rows after a reboot of the Windows Server OS.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just the other day I was asked by a Business Line Manager about the usage patterns of tables in a database that I never seen before. I was lucky that the version of the database was 2005 and Dynamic Management Views existed that stored the requirement information. Today, I am going to review a simple SELECT query that will retrieve the information that we want. The first requirement is to list the schema names that the user tables belong to. We can obtain this information by looking at the sys.schemas&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[732,31,730,12,731,15,28,729,325,326,728,29],"class_list":["post-3958","post","type-post","status-publish","format-standard","hentry","category-db-dev","tag-clustered-index","tag-database-developer","tag-finding-table-info","tag-free-code","tag-heap","tag-john-f-miner-iii","tag-sql-server","tag-sys-dm_db_index_usage_stats","tag-sys-objects","tag-sys-schemas","tag-sys-sysindexes","tag-tsql"],"_links":{"self":[{"href":"https:\/\/craftydba.com\/index.php?rest_route=\/wp\/v2\/posts\/3958","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/craftydba.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/craftydba.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/craftydba.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/craftydba.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3958"}],"version-history":[{"count":0,"href":"https:\/\/craftydba.com\/index.php?rest_route=\/wp\/v2\/posts\/3958\/revisions"}],"wp:attachment":[{"href":"https:\/\/craftydba.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3958"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/craftydba.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3958"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/craftydba.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3958"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}