Elencare le query in esecuzione su SQL Server


200

Esiste un modo per elencare le query attualmente in esecuzione su MS SQL Server (tramite Enterprise Manager o SQL) e / o chi è connesso?

Penso di avere una query molto lunga in esecuzione su uno dei miei server di database e mi piacerebbe rintracciarlo e fermarlo (o la persona che continua ad avviarlo).

Risposte:


203

Questo ti mostrerà gli SPID più lunghi in esecuzione su un server 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

Se hai bisogno di vedere l'SQL in esecuzione per un dato spid dai risultati, usa qualcosa del genere:

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
È possibile modificarlo per funzionare con SQL v12 + (ad es. Azure) rimuovendo i riferimenti al master, ad es. sostituire "master.dbo.sysprocesses" con "dbo.sysprocesses"
Kevin,

Suggerirei di sostituire la msquantizzazione con s. Può verificarsi un possibile trabocco (è successo per me).
Zverev Evgeniy,

Per Azure potresti dover cambiare "master.dbo.sysprocesses" con "sys.sysprocesses"
Danton Heuer,

93

Se si esegue SQL Server 2005 o 2008, è possibile utilizzare i DMV per trovare questo ...

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

1
Questa query non funziona in SQL Server 2005 se il livello di compatibilità del database corrente è inferiore a 90. Se la compatibilità del database corrente è inferiore, passare al db master per eseguire questa query.
Alexander Pravdin,

31

È possibile eseguire il comando sp_who per ottenere un elenco di tutti gli utenti, le sessioni e i processi correnti. È quindi possibile eseguire il comando KILL su qualsiasi spid che sta bloccando gli altri.


3
Questo non è sempre utile. A volte le query sembrano generare spid figlio, specialmente quando vengono utilizzati OPENQUERY o server collegati. Può essere difficile dire quale sia la query principale solo da sp_who.
Nathan,

17

Suggerirei di interrogare le sysviste. qualcosa di simile 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

In questo modo è possibile ottenere un TotalPagesAllocatedche può aiutarti a capire spidche sta prendendo tutte le risorse del server. Ci sono molte volte in cui non riesco nemmeno a visualizzare il monitor delle attività e utilizzare queste sysvisualizzazioni per vedere cosa sta succedendo.

Ti consiglierei di leggere il seguente articolo. Ho preso questo riferimento da qui .


1
Utilizziamo anche l'analisi delle prestazioni di Quest DB che fornisce un'ottima immagine visiva di ciò che accade nel server. Una delle cose brutte è che dice chi è la vittima, ma è difficile capire chi sta consumando le risorse. Ciò aiuterebbe però.
dhi,


11

In realtà, l'esecuzione EXEC sp_who2in Query Analyzer / Management Studio fornisce più informazioni di sp_who.

Oltre a ciò, è possibile configurare SQL Profiler per monitorare tutto il traffico in entrata e in uscita verso il server. Profiler ti consente anche di restringere esattamente quello che stai cercando.

Per SQL Server 2008:

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

Tieni presente che il profiler è davvero un'app di registrazione e visualizzazione. Continuerà a registrare e guardare fino a quando è in esecuzione. Potrebbe riempire file di testo o database o dischi rigidi, quindi fai attenzione a cosa hai guardato e per quanto tempo.


1
SQL Server Profiler è dove tutti dovrebbero iniziare, sicuramente!
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

Come nota, è possibile trovare SQL Server Activity Monitor per SQL Server 2008 facendo clic con il tasto destro del mouse sul server corrente e andando su "Activity Monitor" nel menu contestuale. Ho scoperto che questo era il modo più semplice per terminare i processi se si utilizza SQL Server Management Studio.


Questo avrebbe dovuto essere un commento, ma, sì, è così utile e ottiene più visibilità come risposta :-) E mi ha aiutato in questo momento. Grazie
Loudenvier,

9

In Esplora oggetti, eseguire il drill-down su: Server -> Gestione -> Monitoraggio attività. Ciò ti consentirà di vedere tutte le connessioni al server corrente.


1
Non vedo nulla chiamato Activity Monitor in Management su SQL 2008.
jpierson

5

ecco una query che mostrerà tutte le query che stanno bloccando. Non sono del tutto sicuro che mostrerà solo query lente:

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

La sceneggiatura giusta sarebbe così:

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

È possibile utilizzare la query seguente per trovare l'ultima richiesta in esecuzione:

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

Utilizzando lo script di seguito è inoltre possibile trovare il numero di connessione per database:

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

Per maggiori dettagli, visitare: http://www.dbrnd.com/2015/06/script-to-find-running-process-session-logged-user-in-sql-server/


4

nel 2005 è possibile fare clic con il pulsante destro del mouse su un database, andare ai report e c'è un intero elenco di report su transizioni e blocchi, ecc ...


4

Prova con questo:

Ti fornirà tutte le domande degli utenti. Fino a 50, sono solo sessioni di processo interne al server sql. Ma, se lo desideri, puoi rimuovere la clausola 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

E

KILL @spid

2
andrà bene .. !! e se uccido per spid. ucciderà solo una query? il mio dubbio è spid e session_is sono univoci per ogni query in esecuzione in quella sessione o server?
buttowski,

1

Utilizzare Sql Server Profiler (menu Strumenti) per monitorare l'esecuzione di query e utilizzare Activity Monitor in Management Studio per vedere come è connessa e se la loro connessione sta bloccando altre connessioni.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.