In my Are you ready for SQL Server 2012 or are you still partying like it is 1999? post, I wrote about how you should start using SQL Server 2005 and SQL Server 2008 functionality now in order to prepare for SQL Server 2012. I still see tons of code that is written in the pre 2005 style and people still keep using those functions, procs and statements even though SQL Server 2005 and 2008 have much better functionality.

Today we are going to take a look at Dynamic Management Views. Dynamic Management Views is one of my favorite things that they have added to the SQL Server product. Instead of running all kinds of stored procedures, dbcc commands and selects from table, you can get all that information now from the Dynamic Management Views, all you need to know is what view will get you the information you need.

Let’s take a look at some examples. This query below will give me the top 50 most executed statements in stored procedures

SELECT TOP 50 * FROM(SELECT COALESCE(OBJECT_NAME(s2.objectid),'Ad-Hoc') AS ProcName,execution_count,s2.objectid,
    (SELECT TOP 1 SUBSTRING(s2.TEXT,statement_start_offset / 2+1 ,
      ( (CASE WHEN statement_end_offset = -1
         THEN (LEN(CONVERT(NVARCHAR(MAX),s2.TEXT)) * 2)
         ELSE statement_end_offset END)  - statement_start_offset) / 2+1)) AS sql_statement,
       last_execution_time
FROM sys.dm_exec_query_stats AS s1
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2 ) x
WHERE sql_statement NOT like 'SELECT * FROM(SELECT coalesce(object_name(s2.objectid)%'
and OBJECTPROPERTYEX(x.objectid,'IsProcedure') = 1
and exists (SELECT 1 FROM sys.procedures s
WHERE s.is_ms_shipped = 0
and s.name = x.ProcName )
ORDER BY execution_count DESC

Here is some sample output

proc            count           objectid        statement               last_execution_time
----------------------------------------------------------------------------------------------
usp_AddLast 42757230    517576882   UPDATE dbo.LastSome 2010-04-14 14:15:33.433
usp_AddLast 42757230    517576882   IF EXISTS(   SELECT     2010-04-14 14:15:33.433
usp_Update  20290           725577623   update t  set pclose    2010-04-14 14:15:33.433
usp_Update  20288           725577623   update t  set pclose    2010-04-14 14:15:33.453
usp_GetLast3    3188            501576825   SELECT distinct l.Sy    2010-04-14 14:14:33.350
usp_Historical  168         1029578706  select * from Histor    2010-04-14 14:02:08.190
usp_AddLast 3           517576882   INSERT dbo.Sometable    2010-04-07 08:42:57.040
usp_GetLast2    3           965578478   SELECT l.Symbol,   q    2010-04-06 16:14:49.523
usp_Historical2 2           1045578763  select SomeNumber,G 2010-04-14 12:10:48.860
usp_GetLast 1           901578250   SELECT distinct l.Sy    2010-02-12 09:11:59.840

As you can see the first two rows are for the same stored procedure, what if you only want to know the procedure names? You can use the following query for that, I grouped them by name and then used the max count of the statement itself as the execution count, you could also use SUM instead of MAX. If you have a lot of if else conditions then max might not give you the whole picture.

SELECT TOP 50 * FROM
    (SELECT OBJECT_NAME(s2.objectid) AS ProcName,
        MAX(execution_count) AS execution_count,s2.objectid,
        MAX(last_execution_time) AS last_execution_time
FROM sys.dm_exec_query_stats AS s1
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2
GROUP BY OBJECT_NAME(s2.objectid),s2.objectid) x
WHERE OBJECTPROPERTYEX(x.objectid,'IsProcedure') = 1
AND EXISTS (SELECT 1 FROM sys.procedures s
            WHERE s.is_ms_shipped = 0
            AND s.name = x.ProcName )
ORDER BY execution_count DESC

Here is the output

proc            count           objectid        last_execution_time
----------------------------------------------------------------------
usp_AddLast 42667941    517576882   2010-04-14 14:08:48.287
usp_Update  20263       725577623   2010-04-14 14:08:48.307
usp_GetLast3    3180        501576825   2010-04-14 14:07:10.513
usp_Historical  168     1029578706  2010-04-14 14:02:08.190
usp_GetLast2    3       965578478   2010-04-06 16:14:49.523
usp_Historical2 2       1045578763  2010-04-14 12:10:48.860
usp_GetLast 1       901578250   2010-02-12 09:11:59.840

Imagine doing stuff like this in the SQL Server 2000 days…..better get profiler and some traces running.

What if you want to know the stored procedures with the highest average CPU time in SQL Server? That is pretty easy as well, here is the query for that

SELECT TOP 50 * FROM
    (SELECT OBJECT_NAME(s2.objectid) AS ProcName,
        SUM(s1.total_worker_time/s1.execution_count) AS AverageCPUTime,s2.objectid,
        SUM(execution_count) AS execution_count
FROM sys.dm_exec_query_stats AS s1
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2
GROUP BY OBJECT_NAME(s2.objectid),objectid) x
WHERE OBJECTPROPERTYEX(x.objectid,'IsProcedure') = 1
AND EXISTS (SELECT 1 FROM sys.procedures s
            WHERE s.is_ms_shipped = 0
            AND s.name = x.ProcName )
ORDER BY AverageCPUTime DESC

Output

proc            AverageCPUTime objectid    execution_count
----------------------------------------------------------------------
usp_Update  17152          725577623    41074
usp_GetLast3    333     965578478   3
usp_GetLast2    145     501576825   3237
usp_Historical  70      1029578706  170
usp_AddLast 36      517576882   87154735
usp_GetLast 0       901578250   1
usp_Historical2 0       1045578763  2

Wow, that usp_Update proc really sucks 🙂

Here is another one of my favorite queries. How long will the database restore take?

Run the query below and you will know

SELECT
    d.PERCENT_COMPLETE AS [%Complete],
    d.TOTAL_ELAPSED_TIME/60000 AS ElapsedTimeMin,
    d.ESTIMATED_COMPLETION_TIME/60000   AS TimeRemainingMin,
    d.TOTAL_ELAPSED_TIME*0.00000024 AS ElapsedTimeHours,
    d.ESTIMATED_COMPLETION_TIME*0.00000024  AS TimeRemainingHours,
    s.TEXT AS Command
FROM    sys.dm_exec_requests d
CROSS APPLY sys.dm_exec_sql_text(d.sql_handle)AS s
WHERE  d.COMMAND LIKE 'RESTORE DATABASE%'
ORDER   BY 2 DESC, 3 DESC

For all the sessions that are connected, what state are they in? The query below will give you a quick count

SELECT COUNT(*) AS StatusCount,CASE status
WHEN 'Running' THEN 'Running - Currently running one or more requests'
WHEN 'Sleeping ' THEN 'Sleeping - Currently running no requests'
WHEN 'Preconnect ' THEN 'Session is in the Resource Governor classifier'
ELSE 'Dormant – Session is in prelogin state' END status
FROM sys.dm_exec_sessions
GROUP BY status

Just a quick count of all the transaction isolation levels

SELECT COUNT(*),CASE transaction_isolation_level
WHEN 0 THEN 'Unspecified'
WHEN 1 THEN 'ReadUncomitted'
WHEN 2 THEN 'Readcomitted'
WHEN 3 THEN 'Repeatable'
WHEN 4 THEN 'Serializable'
WHEN 5 THEN 'Snapshot' END AS TRANSACTION_ISOLATION_LEVEL
FROM sys.dm_exec_sessions
GROUP BY transaction_isolation_level

To see what the SET options are that you are using in your connection, use the following query, leave out the WHERE clause if you want to know it for all connections. The query returns pretty much what DBCC USERINFO returns but you can run this for all connected sessions in one shot

SELECT @@SPID AS SPID,
 text_size,
 language,
 lock_timeout,
 date_first,
 date_format,
CASE quoted_identifier
WHEN 1 THEN 'SET' ELSE 'OFF' END QUOTED_IDENTIFIER,
CASE arithabort
WHEN 1 THEN 'SET' ELSE 'OFF' END ARITHABORT,
CASE ansi_null_dflt_on
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_NULL_DFLT_ON,
CASE ansi_defaults
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_DEFAULTS ,
CASE ansi_warnings
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_WARNINGS,
CASE ansi_padding
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_PADDING,
CASE ansi_nulls
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_NULLS,
CASE concat_null_yields_null
WHEN 1 THEN 'SET' ELSE 'OFF' END CONCAT_NULL_YIELDS_NULL,
CASE transaction_isolation_level
WHEN 0 THEN 'Unspecified'
WHEN 1 THEN 'ReadUncomitted'
WHEN 2 THEN 'Readcomitted'
WHEN 3 THEN 'Repeatable'
WHEN 4 THEN 'Serializable'
WHEN 5 THEN 'Snapshot' END AS TRANSACTION_ISOLATION_LEVEL
FROM sys.dm_exec_sessions
WHERE session_id = @@SPID

Here is another one where you had to run performance counter back in the 2000 days. This query will get you the page life expectancy for your server

SELECT *
FROM sys.dm_os_performance_counters  
WHERE counter_name = 'Page life expectancy'
AND OBJECT_NAME = 'SQLServer:Buffer Manager'

Here is another short one, what account are my services running under?

SELECT  distinct servicename,
 service_account,status_desc
FROM    sys.dm_server_services

Output

servicename            service_account         status_desc
SQL Server (MSSQLSERVER)    NT ServiceMSSQLSERVER       Running
SQL Server Agent (MSSQLSERVER)  NT ServiceSQLSERVERAGENT    Stopped

I only listed a handful of Dynamic Management Views, SQL Server 2008 R2 has 135 Dynamic Management Views, SQL Server 2012 as of CTP 3 has 174 Dynamic Management Views

Here is how you can get a list of all of them

SELECT * FROM master.sys.sysobjects
WHERE name like 'dm[_]%'

The list below links to Books On Line for related Dynamic Management Views, if you want to know about mirroring Dynamic Management Views then click on the Database Mirroring Related Dynamic Management Views link. I would say, go to each section and maybe spend a week on it…by the middle of spring you should be the Dynamic Management Views master 🙂

Change Data Capture Related Dynamic Management Views

I/O Related Dynamic Management Views and Functions

Change Tracking Related Dynamic Management Views

Object Related Dynamic Management Views and Functions

Common Language Runtime Related Dynamic Management Views

Query Notifications Related Dynamic Management Views

Database Mirroring Related Dynamic Management Views

Replication Related Dynamic Management Views

Database Related Dynamic Management Views

Resource Governor Dynamic Management Views

Execution Related Dynamic Management Views and Functions

Service Broker Related Dynamic Management Views

Extended Events Dynamic Management Views

SQL Server Operating System Related Dynamic Management Views

Full-Text Search Related Dynamic Management Views

Transaction Related Dynamic Management Views and Functions

Index Related Dynamic Management Views and Functions

Security Related Dynamic Management Views

Filestream-Related Dynamic Management Views (Transact-SQL)

That is all for today, come back tomorrow for the next part in this series