With schools starting for my daughter, I rarely get involved in her daily routine activity. But there is one thing that I don’t try to miss – the parents-teachers meet. Sometimes it is not about the report card on how my daughter faired against the rest in the class but it is more than that. I am curious to understand how she behaves in the class, how she makes friends in class, how her extra-curricular activities are, is she disciplined overall etc. Those are key attributes and traits I am looking at getting as feedback from the teachers in that hour of interactions.
In the same lines, there are tons of other parameters one needs to be aware off with working with SQL Server. A lot of times DBA’s when they are doing maintenance or monitoring of servers, they need help around who is currently accessing the server, what are the inactive sessions, what are the connections with the most resources, all the active sessions on the server and more. This blog will answer these questions. Here are the reports we would talk about:
- Activity – All Cursors
- Activity – Top Cursors
- Activity – All Sessions
- Activity – Top Sessions
- Activity – Dormant Sessions
- Activity – Top Connections
Activity – All Cursors
This report shows information about the cursors used in SQL Server. They are looping construct in T-SQL world. I have probably heard many times, from different sources, as a best practice; avoid using TSQL cursors. In my opinion, there could be situation where cursors might out-perform as compared to other looping constructs. For example, a cursor would be a good candidate for row-by-row processing that can’t be performed by set based operations. We get flexibility via cursor as it provides a subset of data and that allows manipulation of the data in different ways. Having said that, do perform your own performance tests before using the same – these recommendations have to be used with a pinch of salt rather than as written on stone.
The heart of this report is DMV sys.dm_exec_cursors which has a lot of information available about the cursors that are open in various databases. The reports also uses below DMVs.
|sys.dm_exec_sessions||To get login name|
|sys.dm_exec_sql_text||To get text of the statement via sql_handle|
For seeing the sample data into the report, we can run below query
DECLARE cur CURSOR
FOR SELECT name FROM sys.objects
DECLARE @temp SYSNAME
FETCH NEXT FROM cur INTO @temp
WHILE @@fetch_status >= 0
FETCH NEXT FROM cur INTO @temp
WAITFOR delay '00:00:01'
All the values shown are explained in documentation of sys.dm_exec_cursors.
Activity – Top Cursors
This report is same as earlier report and only difference is that we can see them categorized as below.
- Top 10 Oldest Cursors – This shows the oldest cursor the on SQL. (Order by creation_time)
- Top 10 Dormant Cursors – shows Cursor sitting idle since last query (open or fetch) (Order by worker_time)
- Top 10 IO Intensive Cursors – Shows cursors that are consuming the most IO resources. (Order by reads + writes)
- Top 10 CPU Intensive Cursors – Shows cursors that are consuming the most CPU resources. (Order by dormant_duration)
All four sections run exactly same query with different order by clause (which I mentioned in definition) by DMV sys.dm_exec_cursors.
Activity – All Sessions
As the name says – this report shows the details of all sessions, connections, requests and the statements currently active in the server.
This report provides details on all active user sessions on the Instance organized by Login. Since I have started two different login “SlowIO” and “sa”, we are seeing the report shows two groups (highlighted). We can drill down to each group till statement level. Under the hood it uses sys.dm_exec_sessions,
sys.dm_exec_connections and sys.dm_exec_requests DMVs.
Activity – Top Sessions
SELECT TOP 10 s.session_id,
s.cpu_time AS cpu_time,
s.memory_usage * 8 AS memory_usage,
s.total_scheduled_time AS total_scheduled_time,
s.total_elapsed_time AS total_elapsed_time,
COUNT(c.connection_id) AS conn_count
FROM sys.dm_exec_sessions s
LEFT OUTER JOIN sys.dm_exec_connections c
ON ( s.session_id = c.session_id)
LEFT OUTER JOIN sys.dm_exec_requests r
ON ( r.session_id = c.session_id)
WHERE ( s.is_user_process = 1)
GROUP BY s.session_id,
Here are the various order by clauses added in each section. You can do it yourself as well.
- Top Oldest Sessions (order by s.login_time asc)
- Top CPU Consuming Sessions (order by s.cpu_time desc)
- Top Memory Consuming Sessions (order by s.memory_usage desc)
- Top Sessions By # Reads (order by s.reads desc)
- Top Sessions By # Writes (order by s.writes desc)
Activity – Dormant Sessions
This is an interesting report and shows dormant sessions in SQL Server. Dormant session is a session which has connected earlier, ran some query and sitting idle. This report provides details on Sessions that have been inactive for more than an hour. Behind the scene, the report uses sys.dm_exec_sessions and puts filter on datediff(mi, last_request_end_time, @d1) >= 60 to get dormant sessions.
As shown above, there are three sections in the report. In the first section (1), we can see number of All Sessions, number of Dormant Sessions which are there from more than 1 hour and number of users with Dormant Sessions. This might be different from number of sessions, because single login might have more than one session open at a point in time. The second section (2) shows the Top 10 Dormant Sessions. All of the columns are self-explanatory. Third section (3) shows top 10 dormant sessions by user name. This would be useful in development servers where we use user name to find who is connected.
Activity – Top Connections
This is last Activity report in the list. Earlier reports are based on sessions and this report is based on connections. Since this report is similar, I would not explain much.
Here is the base query used by report
SELECT TOP 10 ( Row_number()
ORDER BY c.connect_time) )%2 AS l1,
CONVERT(CHAR(100), c.connection_id) AS connection_id,
FROM sys.dm_exec_requests r
WHERE ( r.connection_id = c.connection_id)) AS request_count,
FROM sys.dm_exec_connections c
LEFT OUTER JOIN sys.dm_exec_sessions s
ON ( s.session_id = c.session_id)
There are three sections. They show similar information but with different order by clauses.
- 10 Oldest Connections – order by c.connect_time
- Top Ten Connections By # Reads – order by c.num_reads desc
- Top Ten Connections By # Writes – order by c.num_writes desc
Well, that was quite a few reports in one go today. I am sure you will play with them and do let me know if you find anything interesting or used these reports in any interesting ways.
Reference: Pinal Dave (http://blog.sqlauthority.com)