web-dev-qa-db-ja.com

SQL Serverを破壊しているものを調べるにはどうすればよいですか?

SQL ServerのCPUは、今日のほとんどの期間で約90%になっています。

継続的に使用されているため、再起動できる状態ではありません。

SQL内でそのようなCPUの過負荷を引き起こしているものを見つけることは可能ですか?

私はSQLプロファイラーを実行しましたが、特に何が起こっているのかを判断するのは非常に困難です。

私はsp_who2を実行しましたが、すべてが正確に何を意味するのか、そしてここで起こりうる問題を特定できるかどうかはわかりません。

「たぶん多く使用されているだけだ」という応答を先取りするために、これは今日、完全に通常の活動レベルから始まったばかりです。

私はSQL内でCPUの悲嘆を引き起こしているものを見つける方法を何とかしています。

59
joshcomley

ここでは、CPUが実際にSQLプロセスによって消費されていることを確認したことをデューデリジェンスと想定しています(perfmonプロセスカテゴリカウンターがこれを確認します)。通常、このような場合は、関連するパフォーマンスカウンターのサンプルを取得し、通常の負荷動作条件で確立したベースラインと比較します。この問題を解決したら、将来の比較のためにこのようなベースラインを確立することをお勧めします。

SQLがすべての単一CPUサイクルに費やしている場所を正確に見つけることができます。しかし、どこを見るかを知るには、多くのノウハウと経験が必要です。 SQL 2005/2008または2000ですか? 2005年以降の幸いなことに、いくつかの既製のソリューションがあります。ジョン・サムソンの答えで、あなたはすでにここにいくつか良いポインタを持っています。 SQL Serverパフォーマンスダッシュボードレポート をダウンロードしてインストールするための推奨事項を追加したいと思います。これらのレポートの一部には、時間別またはI/O別の上位クエリ、最も使用されるデータファイルなどが含まれており、問題の場所をすばやく把握できます。出力は数値とグラフの両方であるため、初心者にとってより便利です。

Adam's Who is Active スクリプトを使用することもお勧めしますが、それはもう少し高度です。

最後になりましたが、パフォーマンス分析に関するMS SQLカスタマーアドバイザリーチームのホワイトペーパーをダウンロードして読むことをお勧めします。 SQL 2005の待機とキュー

また、I/Oを確認することをお勧めします。バッファプールを破壊する負荷をサーバーに追加した場合(つまり、メモリからキャッシュされたデータページを排除するほど多くのデータが必要な場合)、結果としてCPUが大幅に増加します(驚くべきことですが、本当です)。犯人は通常、大きなテーブルをエンドツーエンドでスキャンする新しいクエリです。

26
Remus Rusanu

このクエリはDMVを使用して、CPUごとに最もコストのかかるクエリを識別します

SELECT TOP 20
    qs.sql_handle,
    qs.execution_count,
    qs.total_worker_time AS Total_CPU,
    total_CPU_inSeconds = --Converted from microseconds
        qs.total_worker_time/1000000,
    average_CPU_inSeconds = --Converted from microseconds
        (qs.total_worker_time/1000000) / qs.execution_count,
    qs.total_elapsed_time,
    total_elapsed_time_inSeconds = --Converted from microseconds
        qs.total_elapsed_time/1000000,
    st.text,
    qp.query_plan
FROM
    sys.dm_exec_query_stats AS qs
CROSS APPLY 
    sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS APPLY
    sys.dm_exec_query_plan (qs.plan_handle) AS qp
ORDER BY 
    qs.total_worker_time DESC

完全な説明については、次を参照してください: CPUによって最もコストのかかるSQL Serverクエリを識別する方法

90
John Sansom

SQLプロファイラーを実行し、CPUまたは期間でフィルタリングして、すべての「小さなもの」を除外できます。そうすれば、特定のストアドプロシージャが必要以上に長く実行されているなどの問題があるかどうかを判断するのがはるかに簡単になります(インデックスの欠落など)。

2つの注意事項:

  • 問題が大量の小さなトランザクションである場合、上記で説明したフィルターはそれらを除外し、これを見逃すことになります。
  • また、問題が単一の大規模なジョブ(8時間の分析ジョブや十億行をクロス結合する必要がある適切に設計されていない選択など)である場合、完全に完了するまでプロファイラーでこれが表示されない場合がありますプロファイリングするイベント(sp:completed vs sp:statementcompleted)。

しかし、通常はアクティビティモニターまたはsp_who2から始めます。

7
BradC

これらのいずれかを数秒間隔で実行します。高いCPU接続を検出します。または:ローカル変数に保存されたCPU、WAITFOR DELAY、保存されているCPU値と現在のCPU値を比較する

select * from master..sysprocesses
where status = 'runnable' --comment this out
order by CPU
desc

select * from master..sysprocesses
order by CPU
desc

最もエレガントではないかもしれませんが、効果的かつ迅速です。

5
gbn

GUIアプローチについては、[管理]の下の[アクティビティモニター]を見て、CPUで並べ替えます。

3
cmsjr

ここでいくつかの便利なクエリを見つけることができます:

SQL ServerのCPU使用率が高い原因の調査

私にとって、これは大いに役立ちました:

SELECT s.session_id,
    r.status,
    r.blocking_session_id 'Blk by',
    r.wait_type,
    wait_resource,
    r.wait_time / (1000 * 60) 'Wait M',
    r.cpu_time,
    r.logical_reads,
    r.reads,
    r.writes,
    r.total_elapsed_time / (1000 * 60) 'Elaps M',
    Substring(st.TEXT,(r.statement_start_offset / 2) + 1,
    ((CASE r.statement_end_offset
WHEN -1
THEN Datalength(st.TEXT)
ELSE r.statement_end_offset
END - r.statement_start_offset) / 2) + 1) AS statement_text,
    Coalesce(Quotename(Db_name(st.dbid)) + N'.' + Quotename(Object_schema_name(st.objectid, st.dbid)) + N'.' +
    Quotename(Object_name(st.objectid, st.dbid)), '') AS command_text,
    r.command,
    s.login_name,
    s.Host_name,
    s.program_name,
    s.last_request_end_time,
    s.login_time,
    r.open_transaction_count
FROM sys.dm_exec_sessions AS s
    JOIN sys.dm_exec_requests AS r
ON r.session_id = s.session_id
    CROSS APPLY sys.Dm_exec_sql_text(r.sql_handle) AS st
WHERE r.session_id != @@SPID
ORDER BY r.cpu_time desc

Status、wait_type、cpu_timeの各フィールドで、現在実行中のCPUを最も消費しているタスクを見つけることができます。

3
Saadat