How to get the SQL Server Activity Monitor's output using T-SQL?
To get the exact output as Activity Monitor:
I have modified the given script as follows. You can play the activity monitor on one side and this script in another window and verify the output.
You can also view the currently running expensive queries by using this script and for that just need to do ORDER BY [Total CPU (ms)] desc.
This script will display the following things:
- [Session ID]
- [User Process]
- [Login]
- [Blocked By]
- [Head Blocker]
- [DatabaseName]
- [Task State]
- [Command]
- [statement_text] --It will display the statement which is being executed presently and it can be from the SP or the normal T-sql .
- [command_text] ----- It will display the Stored Procedure's Name.
- [Total CPU (ms)]
- 'Elapsed Time (in Sec)'
- [Wait Time (ms)]
- [Wait Type]
- [Wait Resource]
- [Memory Use (KB)]
- [Host Name]
- [Net Address]
- [Workload Group]
- [Application]
You can also add or remove the columns whichever you need .
I have commented out some columns in the query, like: --[Open Transactions Count] = ISNULL(r.open_transaction_count,0), --[Login Time] = s.login_time, --[Last Request Start Time] = s.last_request_start_time, So if you want can also add or remove the columns as per your requirement and you can also filter out the data DatabaseName wise. I hope this script will help many of us.
/* ACTIVITY MONITOR'S OUTPUT along with statement_text and command_text */ /* Processes */
SELECT [Session ID] = s.session_id,
[User Process] = CONVERT(CHAR(1), s.is_user_process),
[Login] = s.login_name,
[Blocked By] = ISNULL(CONVERT (varchar, w.blocking_session_id), ''),
[Head Blocker] =
CASE
-- session has an active request, is blocked, but is blocking others or session is idle but has an open tran and is blocking others
WHEN r2.session_id IS NOT NULL AND (r.blocking_session_id = 0 OR r.session_id IS NULL) THEN '1'
-- session is either not blocking someone, or is blocking someone but is blocked by another party
ELSE ''
END,
[DatabaseName] = ISNULL(db_name(r.database_id), N''),
[Task State] = ISNULL(t.task_state, N''),
[Command] = ISNULL(r.command, N''),
[statement_text] = Substring(st.TEXT, (r.statement_start_offset / 2) + 1,
( ( CASE r.statement_end_offset WHEN - 1 THEN Datalength(st.TEXT)
ELSE r.statement_end_offset
END - r.statement_start_offset ) / 2 ) + 1), ----It will display the statement which is being executed presently.
[command_text] =Coalesce(Quotename(Db_name(st.dbid)) + N'.' + Quotename(Object_schema_name(st.objectid, st.dbid)) + N'.' + Quotename(Object_name(st.objectid, st.dbid)), ''), -- It will display the Stored Procedure's Name.
[Total CPU (ms)] = r.cpu_time,
r.total_elapsed_time / (1000.0) 'Elapsed Time (in Sec)',
[Wait Time (ms)] = ISNULL(w.wait_duration_ms, 0),
[Wait Type] = ISNULL(w.wait_type, N''),
[Wait Resource] = ISNULL(w.resource_description, N''),
[Total Physical I/O (MB)] = (s.reads + s.writes) * 8 / 1024,
[Memory Use (KB)] = s.memory_usage * 8192 / 1024,
--[Open Transactions Count] = ISNULL(r.open_transaction_count,0),
--[Login Time] = s.login_time,
--[Last Request Start Time] = s.last_request_start_time,
[Host Name] = ISNULL(s.host_name, N''),
[Net Address] = ISNULL(c.client_net_address, N''),
-- [Execution Context ID] = ISNULL(t.exec_context_id, 0),
-- [Request ID] = ISNULL(r.request_id, 0),
[Workload Group] = N'',
[Application] = ISNULL(s.program_name, N'')
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 (s.session_id = r.session_id)
LEFT OUTER JOIN sys.dm_os_tasks t ON (r.session_id = t.session_id
AND r.request_id = t.request_id)
LEFT OUTER JOIN
( -- In some cases (e.g. parallel queries, also waiting for a worker), one thread can be flagged as
-- waiting for several different threads. This will cause that thread to show up in multiple rows
-- in our grid, which we don't want. Use ROW_NUMBER to select the longest wait for each thread,
-- and use it as representative of the other wait relationships this thread is involved in.
SELECT *,
ROW_NUMBER() OVER (PARTITION BY waiting_task_address
ORDER BY wait_duration_ms DESC) AS row_num
FROM sys.dm_os_waiting_tasks ) w ON (t.session_id = w.session_id)
AND w.row_num = 1
LEFT OUTER JOIN sys.dm_exec_requests r2 ON (r.session_id = r2.blocking_session_id) OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) AS st
WHERE s.session_Id > 50 -- Ignore system spids.
ORDER BY s.session_id --,[Total CPU (ms)] desc ;
I also have my scripts to get this done but I strongly recommend sp_whoisactive, that has been widely used, includes a lot of features and can be used for a varied scope of purposes including monitoring.
Just have a look at the following links to get an idea:
How to Use sp_WhoIsActive to Find Slow SQL Server Queries
Whoisactive capturing a SQL server queries Performance Tuning
This query will return very similar information to what activity monitor returns--including the text of the query the process is running.
SELECT
SessionId = s.session_id,
UserProcess = CONVERT(CHAR(1), s.is_user_process),
LoginInfo = s.login_name,
DbInstance = ISNULL(db_name(r.database_id), N''),
TaskState = ISNULL(t.task_state, N''),
Command = ISNULL(r.command, N''),
App = ISNULL(s.program_name, N''),
WaitTime_ms = ISNULL(w.wait_duration_ms, 0),
WaitType = ISNULL(w.wait_type, N''),
WaitResource = ISNULL(w.resource_description, N''),
BlockBy = ISNULL(CONVERT (varchar, w.blocking_session_id), ''),
HeadBlocker =
CASE
-- session has active request; is blocked; blocking others
WHEN r2.session_id IS NOT NULL AND r.blocking_session_id = 0 THEN '1'
-- session idle; has an open tran; blocking others
WHEN r.session_id IS NULL THEN '1'
ELSE ''
END,
TotalCPU_ms = s.cpu_time,
TotalPhyIO_mb = (s.reads + s.writes) * 8 / 1024,
MemUsage_kb = s.memory_usage * 8192 / 1024,
OpenTrans = ISNULL(r.open_transaction_count,0),
LoginTime = s.login_time,
LastReqStartTime = s.last_request_start_time,
HostName = ISNULL(s.host_name, N''),
NetworkAddr = ISNULL(c.client_net_address, N''),
ExecContext = ISNULL(t.exec_context_id, 0),
ReqId = ISNULL(r.request_id, 0),
WorkLoadGrp = N'',
LastCommandBatch = (select text from sys.dm_exec_sql_text(c.most_recent_sql_handle))
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 (s.session_id = r.session_id)
LEFT OUTER JOIN sys.dm_os_tasks t ON (r.session_id = t.session_id AND r.request_id = t.request_id)
LEFT OUTER JOIN
(
-- Using row_number to select longest wait for each thread,
-- should be representative of other wait relationships if thread has multiple involvements.
SELECT *, ROW_NUMBER() OVER (PARTITION BY waiting_task_address ORDER BY wait_duration_ms DESC) AS row_num
FROM sys.dm_os_waiting_tasks
) w ON (t.task_address = w.waiting_task_address) AND w.row_num = 1
LEFT OUTER JOIN sys.dm_exec_requests r2 ON (r.session_id = r2.blocking_session_id)
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) as st
WHERE s.session_Id > 50 -- ignore anything pertaining to the system spids.
AND s.session_Id NOT IN (@@SPID) -- let's avoid our own query! :)
ORDER BY s.session_id;
For your more information about SQL Server Activity Monitor, you can follow the Milena Petrovic Blog Here and also MSDN Blog Here