Lista zapytań uruchomionych na SQL Server


200

Czy istnieje sposób, aby wyświetlić listę zapytań, które są obecnie uruchomione na MS SQL Server (za pośrednictwem Enterprise Manager lub SQL) i / lub kto jest połączony?

Wydaje mi się, że mam bardzo długo działające zapytanie wykonywane na jednym z moich serwerów baz danych i chciałbym je wyśledzić i zatrzymać (lub osobę, która je uruchamia).

Odpowiedzi:


203

Spowoduje to wyświetlenie najdłużej działających identyfikatorów SPID na serwerze SQL 2000 lub 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

Jeśli chcesz zobaczyć, jak SQL działa dla danego pająka z wyników, użyj czegoś takiego:

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
Możesz to zmodyfikować, aby działało z SQL 12 w wersji + (tj. Azure), usuwając odniesienia do wzorca, np. zamień „master.dbo.sysprocesses” na „dbo.sysprocesses”
Kevin

Sugerowałbym zastąpienie mskwantyzacji s. Może wystąpić przepełnienie (stało się dla mnie).
Zverev Evgeniy,

W przypadku platformy Azure może być konieczna zmiana „master.dbo.sysprocesses” na „sys.sysprocesses”
Danton Heuer

93

Jeśli korzystasz z SQL Server 2005 lub 2008, możesz użyć DMV do znalezienia tego ...

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

1
To zapytanie nie działa w SQL Server 2005, jeśli bieżący poziom zgodności bazy danych jest niższy niż 90. Jeśli bieżąca kompatybilność bazy danych jest niższa, przejdź do głównej bazy danych, aby uruchomić to zapytanie.
Alexander Pravdin,

31

Możesz uruchomić polecenie sp_who, aby uzyskać listę wszystkich bieżących użytkowników, sesji i procesów. Następnie możesz uruchomić komendę KILL dla dowolnego pająka, który blokuje inne.


3
To nie zawsze jest pomocne. Czasami wydaje się, że zapytania odradzają dzieci-pająki, szczególnie gdy używane są OPENQUERY lub połączone serwery. Trudno powiedzieć, co jest zapytaniem nadrzędnym tylko ze sp_who.
Nathan

17

Sugerowałbym zapytanie o syswidoki. coś podobnego do

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

W ten sposób możesz uzyskać coś, TotalPagesAllocatedco pomoże ci dowiedzieć się, spidże zajmuje wszystkie zasoby serwera. Wiele razy nie mogę nawet przywołać monitora aktywności i użyć tych syswidoków, aby zobaczyć, co się dzieje.

Poleciłbym przeczytanie następującego artykułu. Mam stąd ten odnośnik .


1
Używamy również analizy wydajności Quest DB, która daje bardzo dobry obraz tego, co dzieje się na serwerze. Jedną ze złych rzeczy jest to, że mówi o tym, kto jest ofiarą, ale trudno jest ustalić, kto zużywa zasoby. To by pomogło.
DHI


11

W rzeczywistości uruchomienie EXEC sp_who2w Query Analyzer / Management Studio daje więcej informacji niż sp_who.

Oprócz tego można skonfigurować SQL Profiler do monitorowania całego ruchu przychodzącego i wychodzącego na serwer. Profiler pozwala również zawęzić dokładnie to, czego szukasz.

W przypadku SQL Server 2008:

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

Pamiętaj, że profiler jest naprawdę aplikacją do logowania i oglądania. Będzie nadal się logować i oglądać tak długo, jak działa. Może wypełniać pliki tekstowe, bazy danych lub dyski twarde, więc bądź ostrożny z tym, co oglądasz i na jak długo.


1
SQL Server Profiler to miejsce, w którym wszyscy powinni zacząć!
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

Uwaga: Monitor aktywności programu SQL Server dla programu SQL Server 2008 można znaleźć, klikając prawym przyciskiem myszy aktualny serwer i przechodząc do menu „Monitor aktywności” w menu kontekstowym. Odkryłem, że jest to najłatwiejszy sposób na zabicie procesów, jeśli używasz SQL Server Management Studio.


To powinien być komentarz, ale tak, jest bardzo przydatny i zyskuje większą widoczność jako odpowiedź :-) I pomógł mi teraz. Dziękuję
Loudenvier

9

W Eksploratorze obiektów przejdź do: Serwer -> Zarządzanie -> Monitor aktywności. Umożliwi to wyświetlenie wszystkich połączeń z bieżącym serwerem.


1
Nie widzę nic o nazwie Monitor aktywności w Zarządzaniu w SQL 2008.
jpierson

5

oto zapytanie, które pokaże wszelkie zapytania, które blokują. Nie jestem do końca pewien, czy pokaże tylko wolne zapytania:

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

Właściwy skrypt wyglądałby tak:

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

Możesz użyć poniższego zapytania, aby znaleźć uruchomione ostatnie żądanie:

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

Za pomocą poniższego skryptu możesz również znaleźć liczbę połączeń na bazę danych:

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

Więcej informacji można znaleźć na stronie: http://www.dbrnd.com/2015/06/script-to-find-running-process-session-logged-user-in-sql-server/


4

w 2005 roku możesz kliknąć bazę danych prawym przyciskiem myszy, przejść do raportów, a cała lista raportów dotyczących przejść i blokad itp.


4

Spróbuj tego:

Zapewni Ci wszystkie zapytania użytkowników. Do spid 50 wszystko to są sesje procesów wewnętrznych serwera SQL. Ale jeśli chcesz, możesz usunąć klauzulę 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

2
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

I

KILL @spid

2
czy będzie dobrze .. !! a jeśli zabiję przez spid. czy to zabije tylko jedno zapytanie? mam wątpliwości, czy spid i session_is są unikalne dla każdego zapytania uruchomionego w tej sesji lub serwerze?
buttowski

1

Użyj Sql Server Profiler (menu narzędzi) do monitorowania wykonywania zapytań i użyj monitora aktywności w Management Studio, aby zobaczyć, jak się łączy i czy ich połączenie blokuje inne połączenia.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.