Liệt kê các truy vấn đang chạy trên SQL Server


200

Có cách nào để liệt kê các truy vấn hiện đang chạy trên MS SQL Server (thông qua Trình quản lý doanh nghiệp hoặc SQL) và / hoặc ai đã kết nối không?

Tôi nghĩ rằng tôi đã có một truy vấn chạy rất lâu đang được thực thi trên một trong các máy chủ cơ sở dữ liệu của mình và tôi muốn theo dõi nó và dừng nó (hoặc người tiếp tục khởi động nó).

Câu trả lời:


203

Điều này sẽ cho bạn thấy các SPID chạy lâu nhất trên máy chủ SQL 2000 hoặc 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

Nếu bạn cần xem SQL chạy cho một kết quả cụ thể từ kết quả, hãy sử dụng một cái gì đó như thế này:

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
Bạn có thể sửa đổi điều này để hoạt động với SQL v12 + (tức là Azure) bằng cách xóa tham chiếu đến chủ, ví dụ: thay thế 'master.dbo.sys Processes' bằng 'dbo.sys Processes'
Kevin

Tôi sẽ đề nghị thay thế mslượng tử hóa bằng s. Một sự cố tràn có thể xảy ra (xảy ra với tôi).
Zverev Evgeniy

Đối với Azure, bạn có thể cần thay đổi "master.dbo.sys Processes" bằng "sys.sys Processes"
Danton Heuer

93

Nếu bạn đang chạy SQL Server 2005 hoặc 2008, bạn có thể sử dụng DMV để tìm ...

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

1
Truy vấn này không hoạt động theo SQL Server 2005 nếu mức độ tương thích cơ sở dữ liệu hiện tại thấp hơn 90. Nếu khả năng tương thích cơ sở dữ liệu hiện tại của bạn thấp hơn, hãy chuyển sang db chính để chạy truy vấn này.
Alexander Pravdin

31

Bạn có thể chạy lệnh sp_who để có danh sách tất cả người dùng, phiên và quy trình hiện tại. Sau đó, bạn có thể chạy lệnh KILL trên bất kỳ spid nào đang chặn người khác.


3
Điều này không phải lúc nào cũng hữu ích. Đôi khi các truy vấn dường như sinh ra các spid con, đặc biệt là khi OPENQUERY hoặc các máy chủ được liên kết đang được sử dụng. Có thể khó để biết đâu là truy vấn chính từ sp_who.
Nathan

17

Tôi sẽ đề nghị truy vấn các sysquan điểm. một cái gì đó tương tự như

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

Bằng cách này, bạn có thể nhận được một TotalPagesAllocatedcái có thể giúp bạn tìm ra thứ spidđang lấy tất cả tài nguyên máy chủ. Có nhiều lúc tôi thậm chí không thể bật màn hình hoạt động và sử dụng các syschế độ xem này để xem những gì đang diễn ra.

Tôi khuyên bạn nên đọc bài viết sau. Tôi có tài liệu tham khảo này từ đây .


1
Chúng tôi cũng sử dụng phân tích Hiệu suất Quest DB cho hình ảnh trực quan rất tốt về những gì đang diễn ra trong máy chủ. Một trong những điều tồi tệ về điều đó là nó cho biết ai là nạn nhân nhưng thật khó để tìm ra ai đang tiêu thụ tài nguyên. Điều này sẽ giúp mặc dù.
dhi

16

Có nhiều quan điểm quản lý được xây dựng trong sản phẩm. Trên SQL 2000 bạn muốn sử dụng sysprocesses . Trên SQL 2K5, có nhiều lượt xem hơn như sys.dm_exec_connections , sys.dm_exec_simessys.dm_exec_Vquests .

Ngoài ra còn có các thủ tục như sp_who tận dụng các quan điểm này. Trong Studio quản lý 2K5, bạn cũng có được Trình giám sát hoạt động.

Và cuối cùng nhưng không kém phần quan trọng là các kịch bản đóng góp của cộng đồng như Ai là chủ động của Adam Machanic .


11

Trên thực tế, việc chạy EXEC sp_who2trong Trình phân tích truy vấn / Studio quản lý cung cấp nhiều thông tin hơn sp_who.

Ngoài ra, bạn có thể thiết lập SQL Profiler để xem tất cả lưu lượng vào và ra đến máy chủ. Profiler cũng cho phép bạn thu hẹp chính xác những gì bạn đang xem.

Đối với SQL Server 2008:

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

Hãy nhớ rằng trình hồ sơ thực sự là một ứng dụng đăng nhập và xem. Nó sẽ tiếp tục đăng nhập và xem chừng nào nó còn chạy. Nó có thể lấp đầy các tệp văn bản hoặc cơ sở dữ liệu hoặc ổ đĩa cứng, vì vậy hãy cẩn thận với những gì bạn có nó xem và trong bao lâu.


1
SQL Server Profiler là nơi mọi người nên bắt đầu, chắc chắn!
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

Lưu ý, có thể tìm thấy Trình theo dõi hoạt động của SQL Server cho SQL Server 2008 bằng cách nhấp chuột phải vào máy chủ hiện tại của bạn và đi đến "Trình giám sát hoạt động" trong menu ngữ cảnh. Tôi thấy đây là cách dễ nhất để tiêu diệt các tiến trình nếu bạn đang sử dụng SQL Server Management Studio.


Điều này đáng lẽ phải là một bình luận, nhưng, vâng, nó rất hữu ích và nó trở nên rõ ràng hơn như một câu trả lời :-) Và nó đã giúp tôi ra ngay bây giờ. Cảm ơn bạn
Lâu đài

9

Trong Object Explorer, xem chi tiết: Máy chủ -> Quản lý -> Giám sát hoạt động. Điều này sẽ cho phép bạn xem tất cả các kết nối trên máy chủ hiện tại.


1
Tôi không thấy bất cứ điều gì được gọi là Trình giám sát hoạt động trong Quản lý trên SQL 2008
jpierson

5

đây là một truy vấn sẽ hiển thị bất kỳ truy vấn nào đang chặn. Tôi không hoàn toàn chắc chắn nếu nó sẽ chỉ hiển thị các truy vấn chậm:

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

Kịch bản đúng sẽ như thế này:

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

Bạn có thể sử dụng truy vấn bên dưới để tìm yêu cầu chạy cuối cùng:

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

Sử dụng tập lệnh bên dưới, bạn cũng có thể tìm thấy số lượng kết nối trên mỗi cơ sở dữ liệu:

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

Để biết thêm chi tiết, vui lòng truy cập: http://www.dbrnd.com/2015/06/script-to-find-rucky- Process-session-loged-user-in-sql-server /


4

năm 2005 bạn có thể nhấp chuột phải vào cơ sở dữ liệu, đi đến báo cáo và có toàn bộ danh sách báo cáo về chuyển đổi và khóa, v.v ...


4

Hãy thử với điều này:

Nó sẽ cung cấp cho bạn tất cả các truy vấn người dùng. Đến năm 50, tất cả đều là phiên xử lý nội bộ của máy chủ sql. Nhưng, nếu bạn muốn, bạn có thể xóa mệnh đề 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

KILL @spid

2
điều này sẽ ổn thôi .. !! và nếu tôi giết bởi spid. điều đó sẽ chỉ giết một truy vấn? nghi ngờ của tôi là spid và session_is là duy nhất cho mỗi truy vấn đang chạy trong phiên hoặc máy chủ đó?
Mông Cổ

1

Sử dụng Sql Server Profiler (menu công cụ) để theo dõi các truy vấn thực hiện và sử dụng trình giám sát hoạt động trong Studio quản lý để xem cách kết nối và nếu kết nối của chúng chặn các kết nối khác.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.