241

Is there a way to list the queries that are currently running on MS SQL Server (either through the Enterprise Manager or SQL) and/or who's connected?

I think I've got a very long running query is being execute on one of my database servers and I'd like to track it down and stop it (or the person who keeps starting it).

BIBD
  • 15,107
  • 25
  • 85
  • 137

17 Answers17

242

This will show you the longest running SPIDs on a SQL 2000 or SQL 2005 server:

select
    P.spid
,   right(convert(varchar, 
            dateadd(ms, datediff(ms, P.last_batch, getdate()), '1900-01-01'), 
            121), 12) as 'batch_duration'
,   P.program_name
,   P.hostname
,   P.loginame
from master.dbo.sysprocesses P
where P.spid > 50
and      P.status not in ('background', 'sleeping')
and      P.cmd not in ('AWAITING COMMAND'
                    ,'MIRROR HANDLER'
                    ,'LAZY WRITER'
                    ,'CHECKPOINT SLEEP'
                    ,'RA MANAGER')
order by batch_duration desc

If you need to see the SQL running for a given spid from the results, use something like this:

declare
    @spid int
,   @stmt_start int
,   @stmt_end int
,   @sql_handle binary(20)

set @spid = XXX -- Fill this in

select  top 1
    @sql_handle = sql_handle
,   @stmt_start = case stmt_start when 0 then 0 else stmt_start / 2 end
,   @stmt_end = case stmt_end when -1 then -1 else stmt_end / 2 end
from    sys.sysprocesses
where   spid = @spid
order by ecid

SELECT
    SUBSTRING(  text,
            COALESCE(NULLIF(@stmt_start, 0), 1),
            CASE @stmt_end
                WHEN -1
                    THEN DATALENGTH(text)
                ELSE
                    (@stmt_end - @stmt_start)
                END
        )
FROM ::fn_get_sql(@sql_handle)
Oscar
  • 13,594
  • 8
  • 47
  • 75
Mike Forman
  • 4,367
  • 1
  • 21
  • 18
  • 5
    You can modify this to work with SQL v12+ (ie. Azure) by removing references to master, eg. replace 'master.dbo.sysprocesses' with 'dbo.sysprocesses' – Kevin Jun 11 '18 at 15:30
  • 1
    I would suggest replacing the `ms` quantization with `s`. A possible overflow can occur (happened for me). – Zverev Evgeniy Sep 17 '19 at 19:47
  • For Azure you might need to change "master.dbo.sysprocesses" with "sys.sysprocesses" – Danton Heuer Apr 28 '20 at 00:42
112

If you're running SQL Server 2005 or 2008, you could use the DMV's to find this...

SELECT  *
FROM    sys.dm_exec_requests  
        CROSS APPLY sys.dm_exec_sql_text(sql_handle)  
shA.t
  • 16,580
  • 5
  • 54
  • 111
Scott Ivey
  • 40,768
  • 21
  • 80
  • 118
  • 1
    This query is not working under SQL Server 2005 if the current database compatibility level is lower than 90. If your current database compatibility is lower, switch to the master db to run this query. – Alexander Pravdin Nov 10 '17 at 08:38
36

You can run the sp_who command to get a list of all the current users, sessions and processes. You can then run the KILL command on any spid that is blocking others.

ichiban
  • 6,162
  • 3
  • 27
  • 34
  • 3
    This is not always helpful. Sometimes queries seem to spawn child spid's, especially when OPENQUERY or linked servers are being used. It can be hard to tell what is the parent query just from sp_who. – Nathan Dec 22 '10 at 03:04
21

As a note, the SQL Server Activity Monitor for SQL Server 2008 can be found by right clicking your current server and going to "Activity Monitor" in the context menu. I found this was easiest way to kill processes if you are using the SQL Server Management Studio.

ChrisM
  • 1,576
  • 6
  • 18
  • 29
prenster
  • 311
  • 2
  • 3
  • This should have been a comment, but, yes, it is so useful and it gets more visibility as an answer :-) And it helped me out right now. Thank you – Loudenvier Feb 28 '18 at 14:52
  • 1
    @Loudenvier you know, you're totally right.... I guess I'm glad I was ignorant of the finer points of posting on stackoverflow at the time. Glad it helped!! – prenster Jun 07 '22 at 01:28
20

I would suggest querying the sys views. something similar to

SELECT * 
FROM 
   sys.dm_exec_sessions s
   LEFT  JOIN sys.dm_exec_connections c
        ON  s.session_id = c.session_id
   LEFT JOIN sys.dm_db_task_space_usage tsu
        ON  tsu.session_id = s.session_id
   LEFT JOIN sys.dm_os_tasks t
        ON  t.session_id = tsu.session_id
        AND t.request_id = tsu.request_id
   LEFT JOIN sys.dm_exec_requests r
        ON  r.session_id = tsu.session_id
        AND r.request_id = tsu.request_id
   OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) TSQL

This way you can get a TotalPagesAllocated which can help you figure out the spid that is taking all the server resources. There has lots of times when I can't even bring up activity monitor and use these sys views to see what's going on.

I would recommend you reading the following article. I got this reference from here.

shA.t
  • 16,580
  • 5
  • 54
  • 111
dhi
  • 1,115
  • 8
  • 3
  • 1
    We also use Quest DB Performance analysis that gives a very good visual picture of whats going on in the server. One of the bad things about that is it tells who is victim but its hard to figure out who is consuming the resources. This would help though. – dhi Jun 18 '12 at 23:39
17

There are various management views built into the product. On SQL 2000 you'd use sysprocesses. On SQL 2K5 there are more views like sys.dm_exec_connections, sys.dm_exec_sessions and sys.dm_exec_requests.

There are also procedures like sp_who that leverage these views. In 2K5 Management Studio you also get Activity Monitor.

And last but not least there are community contributed scripts like the Who Is Active by Adam Machanic.

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
13
SELECT
    p.spid, p.status, p.hostname, p.loginame, p.cpu, r.start_time, r.command,
    p.program_name, text 
FROM
    sys.dm_exec_requests AS r,
    master.dbo.sysprocesses AS p 
    CROSS APPLY sys.dm_exec_sql_text(p.sql_handle)
WHERE
    p.status NOT IN ('sleeping', 'background') 
AND r.session_id = p.spid
shA.t
  • 16,580
  • 5
  • 54
  • 111
Howard Rothenburg
  • 1,220
  • 1
  • 11
  • 7
12

Actually, running EXEC sp_who2 in Query Analyzer / Management Studio gives more info than sp_who.

Beyond that you could set up SQL Profiler to watch all of the in and out traffic to the server. Profiler also let you narrow down exactly what you are watching for.

For SQL Server 2008:

START - All Programs - Microsoft SQL Server 2008 - Performance Tools - SQL Server Profiler

Keep in mind that the profiler is truly a logging and watching app. It will continue to log and watch as long as it is running. It could fill up text files or databases or hard drives, so be careful what you have it watch and for how long.

shA.t
  • 16,580
  • 5
  • 54
  • 111
tlatourelle
  • 596
  • 5
  • 15
9

In the Object Explorer, drill-down to: Server -> Management -> Activity Monitor. This will allow you to see all connections on to the current server.

Tyler
  • 514
  • 2
  • 9
6

You can use below query to find running last request:

SELECT
    der.session_id
    ,est.TEXT AS QueryText
    ,der.status
    ,der.blocking_session_id
    ,der.cpu_time
    ,der.total_elapsed_time
FROM sys.dm_exec_requests AS der
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS est

Using below script you can also find number of connection per database:

SELECT 
    DB_NAME(DBID) AS DataBaseName
    ,COUNT(DBID) AS NumberOfConnections
    ,LogiName 
FROM sys.sysprocesses
WHERE DBID > 0
GROUP BY DBID, LogiName

For more details please visit: http://www.dbrnd.com/2015/06/script-to-find-running-process-session-logged-user-in-sql-server/

Anvesh
  • 7,103
  • 3
  • 45
  • 43
5
SELECT 
    p.spid, p.status, p.hostname, p.loginame, p.cpu, r.start_time, t.text
FROM
    sys.dm_exec_requests as r,
    master.dbo.sysprocesses as p
    CROSS APPLY sys.dm_exec_sql_text(p.sql_handle) t
WHERE
    p.status NOT IN ('sleeping', 'background')
AND r.session_id = p.spid

And

KILL @spid
shA.t
  • 16,580
  • 5
  • 54
  • 111
buttowski
  • 4,657
  • 8
  • 27
  • 33
  • 2
    will this is be fine.. !! and if i kill by spid. will that kill only one query ? my doubt is spid and session_is are unique to each query that is running in that session or server ? – buttowski Oct 24 '12 at 12:51
5

The right script would be like this:

select 
p.spid, p.status,p.hostname,p.loginame,p.cpu,r.start_time, t.text
    from sys.dm_exec_requests as r, sys.sysprocesses p 
    cross apply sys.dm_exec_sql_text(p.sql_handle) t
    where p.status not in ('sleeping', 'background')
    and r.session_id=p.spid
5

here is a query that will show any queries that are blocking. I am not entirely sure if it will just show slow queries:

SELECT p.spid
,convert(char(12), d.name) db_name
, program_name
, convert(char(12), l.name) login_name
, convert(char(12), hostname) hostname
, cmd
, p.status
, p.blocked
, login_time
, last_batch
, p.spid
FROM      master..sysprocesses p
JOIN      master..sysdatabases d ON p.dbid =  d.dbid
JOIN      master..syslogins l ON p.sid = l.sid
WHERE     p.blocked = 0
AND       EXISTS (  SELECT 1
          FROM      master..sysprocesses p2
          WHERE     p2.blocked = p.spid )
Steve Stedman
  • 713
  • 2
  • 7
  • 10
4

in 2005 you can right click on a database, go to reports and there's a whole list of reports on transitions and locks etc...

DForck42
  • 19,789
  • 13
  • 59
  • 84
3

Trying to put things together (hope to be helpful):

SELECT
    p.spid,
    RIGHT(CONVERT(varchar, DATEADD(ms, DATEDIFF(ms, p.last_batch, GETDATE()), '1900-01-01'), 121), 12) AS [batch_duration],
    p.[program_name],
    p.hostname,
    MAX(p.loginame) AS loginame,
    (SELECT SUBSTRING(text, COALESCE(NULLIF(spid.stmt_start, 0), 1) + 1, CASE spid.stmt_end WHEN -1 THEN DATALENGTH(text) ELSE (spid.stmt_end - spid.stmt_start) END) FROM ::fn_get_sql(spid.[sql_handle])) AS [sql]
FROM
    master.dbo.sysprocesses p
    LEFT JOIN (
        SELECT
            ROW_NUMBER() OVER(PARTITION BY spid ORDER BY ecid) AS i,
            spid,
            [sql_handle],
            CASE stmt_start WHEN 0 THEN 0 ELSE stmt_start / 2 END AS stmt_start,
            CASE stmt_end WHEN -1 THEN -1 ELSE stmt_end / 2 END AS stmt_end
        FROM sys.sysprocesses
    ) spid ON p.spid = spid.spid AND spid.i = 1
WHERE
    p.spid > 50
    AND p.status NOT IN ('background', 'sleeping')
    AND p.cmd NOT IN ('AWAITING COMMAND', 'MIRROR HANDLER', 'LAZY WRITER', 'CHECKPOINT SLEEP', 'RA MANAGER')
GROUP BY
    p.spid,
    p.last_batch,
    p.[program_name],
    p.hostname,
    spid.stmt_start,
    spid.stmt_end,
    spid.[sql_handle]
ORDER BY
    batch_duration DESC,
    p.spid
;
d.angellotti
  • 124
  • 1
  • 1
  • 8
2

You should try very usefull procedure sp_whoIsActive which can be found here: http://whoisactive.com and it is free.

Saša
  • 4,416
  • 1
  • 27
  • 41
2

Use Sql Server Profiler (tools menu) to monitor executing queries and use activity monitor in Management studio to see how is connected and if their connection is blocking other connections.

Beatles1692
  • 5,214
  • 34
  • 65