Listar las consultas que se ejecutan en SQL Server


200

¿Hay alguna forma de enumerar las consultas que se ejecutan actualmente en MS SQL Server (ya sea a través del Administrador corporativo o SQL) y / o quién está conectado?

Creo que tengo una consulta de ejecución muy larga que se está ejecutando en uno de mis servidores de bases de datos y me gustaría rastrearla y detenerla (o la persona que sigue iniciando).

Respuestas:


203

Esto le mostrará los SPID de mayor duración en un servidor SQL 2000 o SQL 2005:

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

Si necesita ver el SQL ejecutándose para un spid determinado a partir de los resultados, use algo como esto:

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)

3
Puede modificar esto para que funcione con SQL v12 + (es decir, Azure) eliminando referencias al maestro, por ejemplo. reemplace 'master.dbo.sysprocesses' con 'dbo.sysprocesses'
Kevin

Sugeriría reemplazar la mscuantización con s. Puede ocurrir un posible desbordamiento (sucedió para mí).
Zverev Evgeniy

Para Azure, es posible que deba cambiar "master.dbo.sysprocesses" con "sys.sysprocesses"
Danton Heuer

93

Si está ejecutando SQL Server 2005 o 2008, podría usar los DMV para encontrar esto ...

SELECT  *
FROM    sys.dm_exec_requests  
        CROSS APPLY sys.dm_exec_sql_text(sql_handle)  

1
Esta consulta no funciona en SQL Server 2005 si el nivel de compatibilidad de la base de datos actual es inferior a 90. Si la compatibilidad de su base de datos actual es inferior, cambie a la base de datos maestra para ejecutar esta consulta.
Alexander Pravdin

31

Puede ejecutar el comando sp_who para obtener una lista de todos los usuarios, sesiones y procesos actuales. Luego puede ejecutar el comando KILL en cualquier spid que esté bloqueando a otros.


3
Esto no siempre es útil. A veces, las consultas parecen generar spid secundarios, especialmente cuando se está utilizando OPENQUERY o servidores vinculados. Puede ser difícil saber cuál es la consulta principal solo desde sp_who.
Nathan

17

Sugeriría consultar las sysvistas. algo similar a

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

De esta manera, puede obtener una TotalPagesAllocatedque puede ayudarlo a descubrir spidqué está tomando todos los recursos del servidor. Hay muchas veces en que ni siquiera puedo abrir el monitor de actividad y usar estas sysvistas para ver qué está pasando.

Te recomendaría leer el siguiente artículo. Tengo esta referencia de aquí .


1
También utilizamos el análisis de rendimiento Quest DB que ofrece una muy buena imagen visual de lo que sucede en el servidor. Una de las cosas malas de esto es que dice quién es la víctima, pero es difícil determinar quién está consumiendo los recursos. Sin embargo, esto ayudaría.
dhi


11

En realidad, ejecutar EXEC sp_who2en Query Analyzer / Management Studio da más información que sp_who.

Más allá de eso, puede configurar SQL Profiler para ver todo el tráfico de entrada y salida al servidor. Profiler también te permite reducir exactamente lo que estás viendo.

Para SQL Server 2008:

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

Tenga en cuenta que el generador de perfiles es realmente una aplicación de registro y observación. Continuará registrando y observando mientras se esté ejecutando. Podría llenar archivos de texto o bases de datos o discos duros, así que tenga cuidado con lo que tiene que ver y por cuánto tiempo.


1
¡SQL Server Profiler es donde todos deberían comenzar, definitivamente!
Shane

11
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

11

Como nota, puede encontrar el Monitor de actividad de SQL Server para SQL Server 2008 haciendo clic derecho en su servidor actual y yendo a "Monitor de actividad" en el menú contextual. Descubrí que esta era la forma más fácil de eliminar procesos si está utilizando SQL Server Management Studio.


Esto debería haber sido un comentario, pero sí, es muy útil y tiene más visibilidad como respuesta :-) Y me ayudó en este momento. Gracias
Loudenvier

9

En el Explorador de objetos, acceda a: Servidor -> Administración -> Monitor de actividad. Esto le permitirá ver todas las conexiones al servidor actual.


1
No veo nada llamado Monitor de actividad bajo administración en SQL 2008.
jpierson

5

Aquí hay una consulta que mostrará cualquier consulta que esté bloqueando. No estoy completamente seguro de si solo mostrará consultas lentas:

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 )

5

El guión correcto sería así:

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

Puede usar la consulta a continuación para encontrar la última solicitud en ejecución:

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

Usando el siguiente script también puede encontrar el número de conexiones por base de datos:

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

Para obtener más detalles, visite: http://www.dbrnd.com/2015/06/script-to-find-running-process-session-logged-user-in-sql-server/


4

en 2005 puede hacer clic derecho en una base de datos, ir a informes y hay una lista completa de informes sobre transiciones y bloqueos, etc.


4

Prueba con esto:

Le proporcionará todas las consultas de los usuarios. Hasta spid 50, todo son sesiones de proceso interno del servidor sql. Pero, si lo desea, puede eliminar la cláusula where:

select
r.session_id,
r.start_time,
s.login_name,
c.client_net_address,
s.host_name,
s.program_name,
st.text
from sys.dm_exec_requests r
inner join sys.dm_exec_sessions s
on r.session_id = s.session_id
left join sys.dm_exec_connections c
on r.session_id = c.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st where r.session_id  > 50

3
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

Y

KILL @spid

2
esto estara bien .. !! y si mato por spid. ¿matará eso solo una consulta? mi duda es spid y session_is son exclusivas de cada consulta que se ejecuta en esa sesión o servidor?
buttowski

1

Use Sql Server Profiler (menú de herramientas) para monitorear la ejecución de consultas y use el monitor de actividad en Management studio para ver cómo está conectado y si su conexión está bloqueando otras conexiones.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.