SQL Serverで実行されているクエリを一覧表示する


200

現在Enterprise ManagerまたはSQLを介してMS SQL Serverで実行されているクエリや接続しているクエリを一覧表示する方法はありますか?

私のデータベースサーバーの1つで非常に長時間実行されているクエリが実行されていると思います。それを追跡して停止します(またはそれを開始し続ける人)。

回答:


203

これにより、SQL 2000またはSQL 2005サーバーで最も長く実行されているSPIDが表示されます。

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

結果から特定のspidに対して実行されているSQLを確認する必要がある場合は、次のようなものを使用します。

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
マスターへの参照を削除することで、SQL v12 +(Azureなど)で動作するようにこれを変更できます。「master.dbo.sysprocesses」を「dbo.sysprocesses」に置き換えます
Kevin

ms量子化をに置き換えることをお勧めしsます。オーバーフローが発生する可能性があります(私にとっては)。
Zverev Evgeniy

Azureの場合、「master.dbo.sysprocesses」を「sys.sysprocesses」に変更する必要があるかもしれません
Danton Heuer

93

SQL Server 2005または2008を実行している場合、DMVを使用してこれを見つけることができます...

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

1
現在のデータベースの互換性レベルが90未満の場合、このクエリはSQL Server 2005では機能しません。現在のデータベースの互換性が低い場合は、マスターデータベースに切り替えてこのクエリを実行してください。
Alexander Pravdin 2017年

31

sp_whoコマンドを実行して、現在のすべてのユーザー、セッション、およびプロセスのリストを取得できます。次に、他をブロックしている任意のspidに対してKILLコマンドを実行できます。


3
これは常に役立つとは限りません。特にOPENQUERYまたはリンクサーバーが使用されている場合は特に、クエリが子spidを生成するように見えることがあります。sp_whoだけから親クエリが何であるかを見分けるのは難しい場合があります。
ネイサン

17

sysビューをクエリすることをお勧めします。に似たもの

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

この方法で、すべてのサーバーリソースを使用TotalPagesAllocatedしてspidいるを理解するのに役立つを取得できます。アクティビティモニターを表示できず、これらのsysビューを使用して何が起こっているのかを確認できないことがよくあります。

次の記事を読むことをお勧めします。こちらから参考になりました


1
また、サーバーで行われていることを非常に視覚的に示すQuest DB Performance分析も使用します。これの悪い点の1つは、誰が犠牲者であるかがわかりますが、誰がリソースを消費しているかを理解するのが難しいことです。これは役に立ちます。
dhi

16

製品にはさまざまな管理ビューが組み込まれています。SQL 2000では、sysprocessesを使用します。SQL 2K5 ではsys.dm_exec_connectionssys.dm_exec_sessionssys.dm_exec_requestsなどのビューがさらにあります。

これらのビューを活用するsp_whoのようなプロシージャもあります。2K5 Management Studioでは、アクティビティモニターも利用できます。

そして最後に、コミュニティの貢献によるスクリプトがあります。 重要なことですが、Adam MachanicによるWho Is Active


11

実際にはEXEC sp_who2、クエリアナライザー/ Management Studio で実行すると、sp_who

さらに、サーバーへのすべての入出力トラフィックを監視するようにSQLプロファイラーを設定することもできます。プロファイラーを使用すると、監視対象を正確に絞り込むこともできます。

SQL Server 2008の場合:

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

プロファイラーは本当にログ記録と監視のアプリであることに注意してください。それが実行されている限り、ログを記録して監視し続けます。テキストファイル、データベース、またはハードドライブがいっぱいになる可能性があるので、何をどのくらい見ているか注意してください。


1
SQL Server Profilerは、誰もが始めるべき場所です。
シェーン

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

注意として、SQL Server 2008のSQL Serverアクティビティモニターは、現在のサーバーを右クリックして、コンテキストメニューの[アクティビティモニター]に移動すると見つかります。SQL Server Management Studioを使用している場合、これがプロセスを強制終了する最も簡単な方法であることがわかりました。


これはコメントであるべきでしたが、そうです、それはとても便利で、答えとしてより多くの可視性を得ます:-)そして、それは今私を助けました。ありがとう
Loudenvier 2018

9

オブジェクトエクスプローラーで、[サーバー]-> [管理]-> [アクティビティモニター]にドリルダウンします。これにより、現在のサーバーへのすべての接続を確認できます。


1
私はSQLに2008年の管理の下でアクティビティモニタと呼ばれる何も表示されません
jpierson

5

これは、ブロックしているクエリを表示するクエリです。それが遅いクエリを表示するだけかどうかは完全にはわかりません:

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

適切なスクリプトは次のようになります。

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

以下のクエリを使用して、実行中の最後のリクエストを見つけることができます。

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

以下のスクリプトを使用すると、データベースごとの接続数も確認できます。

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

詳細については、http//www.dbrnd.com/2015/06/script-to-find-running-process-session-logged-user-in-sql-server/をご覧ください。


4

2005年には、データベースを右クリックしてレポートに移動すると、遷移やロックなどに関するレポートの完全なリストがあります...


4

これで試してください:

それはあなたにすべてのユーザークエリを提供します。spid 50までは、すべてSQLサーバーの内部プロセスセッションです。ただし、必要に応じて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

そして

KILL @spid

2
これは大丈夫でしょうか.. !! と私はspidで殺す場合。それは1つのクエリだけを殺しますか?私の疑問はspidであり、session_isはそのセッションまたはサーバーで実行されている各クエリに固有ですか?
buttowski 2012年

1

Sql Server Profiler(ツールメニュー)を使用して実行中のクエリを監視し、Management Studioでアクティビティモニターを使用して、接続方法と、それらの接続が他の接続をブロックしているかどうかを確認します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.