78

私のSQLServerCPUは、今日のほとんどの部分で約90%になっています。

常時使用しているため、再起動できません。

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

私はSQLプロファイラーを実行しましたが、特に何かがそれを引き起こしているかどうかを判断するのは難しいです。

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

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

私はSQL内でCPUの問題を引き起こしている原因を見つける方法を探しています。

4

6 に答える 6

110

このクエリは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によって最もコストのかかるSQLServerクエリを特定する方法」を参照してください。

于 2009-06-03T15:01:42.197 に答える
33

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

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

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

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

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

于 2009-06-03T18:01:07.197 に答える
9

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

SQLServerの高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、現在実行されている最もCPUを消費するタスクwait_typecpu_time見つけることができます。

于 2018-11-05T10:57:34.347 に答える
7

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

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

select * from master..sysprocesses
order by CPU
desc

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

于 2009-06-03T14:29:11.747 に答える
7

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

2つの警告:

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

しかし、通常、私はActivityMonitorまたはsp_who2から始めます。

于 2009-06-03T14:58:52.840 に答える
3

GUIアプローチについては、Managementの下のActivity Monitorを見て、CPUで並べ替えます。

于 2009-06-03T14:40:33.253 に答える