web-dev-qa-db-ja.com

SQL ServerのCPU使用率が過負荷になることがある

サーバーは2つあります。1つはSQLなしのWebサイト専用で、もう1つはSQL専用です。

これで、SQLを実行しているサーバーは非常に強力ですが、サーバーのCPUが100%に達することもあります。

ここに何が起こっているかを示すスクリーンショットのカップルです。

CPUの最大値:

enter image description here

正常に実行されているCPU:

enter image description here

ご覧のとおり、サーバーは非常に強力です。

その他の注意事項。

  1. Nopcommerceバージョン3.70を実行しています
  2. このWebサイトは、他の開発者によって大幅にカスタマイズされています。
  3. ウェブサイトには約4000〜5000の製品があります。
  4. CPUが最大になると、ロード時間が衝撃的になります。 > 30秒、時には1分以上。

誰かが何が起こっているのかについていくつかの光を当てたり、確認するためにいくつかのことを私に案内することができますか?.

乾杯

更新:次の2つのスクリーンショットは、@ S4V1Nが実行を提案した2つのクエリの結果です。

enter image description here

enter image description here

1
Web Dev Guy

誰かが何が起こっているのかについていくつかの光を当てたり、確認するためにいくつかのことを私に案内することができますか?.

明白なものから始めましょう。本番SQLボックスのサーバーは、それほど強力ではありません。たとえば、 これは私が開発作業をしているものです であり、私はほとんどの場合、単なるコンサルタントです。

NUTS

そうは言っても、ハードウェアを増やしても問題をすべて解決できるとは限りません。私はあなたが言及したプラットフォームに精通していませんが、通常はベース製品から始めて、それを「高度にカスタマイズされた」と呼び始めるとき、つまり、ベース製品で動作するために使用されていたコードとインデックスはおそらくtはもううまくいきます。

何から始められますか?

私が働いている会社 無料のスクリプトを書く は、これらの根本に到達するのに役立ちます。それがハードウェアで修正できるものか、ベンダーのサポートで修正できるものかは、別の問題です。

多くのベンダーは、あなたが彼らの製品に変更を加えることを嫌っています。しかし、ねえ、少なくともあなたは変更を加えることについての会話を始めることができます。

  1. Sp_Blitzを実行する

EXEC sp_Blitz @CheckUserDatabaseObjects = 1, @CheckServerInfo = 1;

これにより、サーバーで正常に何が起こっているかについての一般的な考えが得られます。ここでいくつかの設定に注意してください:並列処理のMAXDOPとコストのしきい値。状況が変化する理由については ここに私の回答 を参照してください。

  1. Sp_BlitzFirstを実行する

EXEC sp_BlitzFirst @SinceStartup = 1;

これにより、サーバーの起動後の状態がわかります。待機統計ペインを見て、ボトルネックがどこにあるかを確認します。

NUTS

  1. Sp_BlitzCacheを実行します。

EXEC sp_BlitzCache @SortOrder = 'cpu';

NUTS

プランのキャッシュが気になるので、まずCPUで確認してください。他のソート順もすぐに役立つかもしれませんが、ここから始めてください。

クエリプランのあらゆる種類のものについて警告し、できるだけ多くの履歴情報を提供します。

  1. Sp_BlitzIndexを実行する

EXEC sp_BlitzIndex @DatabaseName = N'YourDatabaseName', @Mode = 4

ここで確認する必要がある主なものは、値の高い欠損インデックスです。これは、一番上にあるはずです。

  1. CPUの急上昇を見つけたら、sp_BlitzWhoを実行します。

EXEC sp_BlitzWho

これにより、CPU使用率が高いときに実行されているクエリがわかります。それらは、プランキャッシュの内容と異なる場合があります。

お役に立てれば!

4
Erik Darling

タスクマネージャーを使用してCPU使用率を監視することは、信頼できるソースではありません。他にも(コアOSアクティビティ、デバイスドライバーなど)非SQLプロセスがバックグラウンドで実行されているため、知らないうちにオーバーヘッドが追加される可能性があります。

PerfMonは、これらの場合に到達する必要があるツールです。

Processor /%Privileged Time、Processor /%User Time、Process(sqlservr.exe)/%Processor Time

これらの各カウンターを説明せずに、SQLサーバーで実際に何が起こっているかを理解し、説明のチェックボックスをオンにしてそこから読み取りますが、基本的に、SQLサーバーと他のプロセスの使用率の比率が表示されます。

発見は簡単ですが、診断はそれほど簡単ではありません。プロセッサに問題があることを示す他の「隠れた」問題がある可能性があります。多くのコンパイル/再コンパイルがあることなど。これは、パラメータ化されていないクエリまたは強制的な再コンパイルに関連する問題です。これらのメトリックはPerfmonで確認できます:SQLServer:SQL Statistics/SQL Compilations/sec、SQLServer:SQL Statistics/SQL Re-Compilations/sec

SQLServer:プランキャッシュ/キャッシュヒット率メモリの問題を示しますが、メモリの過剰なページフラッシュイン/アウトもCPU使用率を追加します。

DMVは、問題の診断にも役立ちます。

SELECT TOP ( 10 )
wait_type ,
waiting_tasks_count ,
( wait_time_ms - signal_wait_time_ms ) AS resource_wait_time ,
max_wait_time_ms ,
CASE waiting_tasks_count
WHEN 0 THEN 0
ELSE wait_time_ms / waiting_tasks_count
END AS avg_wait_time
FROM sys.dm_os_wait_stats
WHERE wait_type NOT LIKE '%SLEEP%' 
AND wait_type NOT LIKE 'XE%'
AND wait_type NOT IN
( 'KSOURCE_WAKEUP', 'BROKER_TASK_STOP', 'FT_IFTS_SCHEDULER_IDLE_WAIT',
'SQLTRACE_BUFFER_FLUSH', 'CLR_AUTO_EVENT', 'BROKER_EVENTHANDLER',
'BAD_PAGE_PROCESS', 'BROKER_TRANSMITTER', 'CHECKPOINT_QUEUE',
'DBMIRROR_EVENTS_QUEUE', 'SQLTRACE_BUFFER_FLUSH', 'CLR_MANUAL_EVENT',
'ONDEMAND_TASK_QUEUE', 'REQUEST_FOR_DEADLOCK_SEARCH', 'LOGMGR_QUEUE',
'BROKER_RECEIVE_WAITFOR', 'PREEMPTIVE_OS_GETPROCADDRESS',
'PREEMPTIVE_OS_AUTHENTICATIONOPS', 'BROKER_TO_FLUSH' )
ORDER BY wait_time_ms DESC

SOS_SCHEDULER_YIELDとCXPACKETの待機が見つかるかどうかを確認します。 SOS_SCHEDULER_YIELDの待機時間が長い場合、CPUに非常に広範囲にわたるクエリが発生する可能性があるため、注意が必要です。この:

SELECT TOP ( 10 )
SUBSTRING(ST.text, ( QS.statement_start_offset / 2 ) + 1,
( ( CASE statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE QS.statement_end_offset
END - QS.statement_start_offset ) / 2 ) + 1)
AS statement_text ,
total_worker_time / 1000 AS total_worker_time_ms ,
( total_worker_time / 1000 ) / execution_count
AS avg_worker_time_ms ,
total_logical_reads ,
total_logical_reads / execution_count AS avg_logical_reads ,
total_elapsed_time / 1000 AS total_elapsed_time_ms ,
( total_elapsed_time / 1000 ) / execution_count
AS avg_elapsed_time_ms ,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY total_worker_time DESC

さらに最適化する必要があると思われる、最もCPUが多いクエリが表示されます。

これらのクエリを最適化すると、欠落したインデックス、古い統計、高いCPU使用率の背後にある実際の問題である、検索できないクエリが見つかる可能性があります。

CPUの問題を解決するための唯一の青写真ではありませんが、良いスタートを切ることができれば幸いです。

2
S4V1N

おそらく2つのことが起こっています。

以下から始めましょう。SQLServerのほとんどのユースケースでは、CPUは最も負担の少ない要素です。オーバーロードしないだけです。限目。いくつかの例外はありますが、99%のケースでは、CPUの過負荷は、SQLまたはテーブルの設計が原因でSQLサーバーが大量のCPUサイクルを浪費し、実際には不要なデータ変換を行っていることが原因と考えられます。

例:表1には整数のIDフィールドがあり、表2はそれを参照していますが、外部キーは文字(数値を格納)です。すべての結合でのデータ変換へようこそ-完全に回避可能で、一般に、修正が容易な(データ型などを見落とす)小さな「愚かな」間違い。ほぼ同じくらい悪いのは、ルックアップにNVarchar(SQL Serverの)文字フィールドを使用することです。Unicode文字列の比較ルールは複雑で、N(たとえば、製品コードテーブルの場合)は、純粋なVARCHAR(これは、 Unicodeを処理しない)。必要な場合もあれば、ばかげた規制の場合もあります(すべてのフィールドはUnicodeであり、電話番号のようなものも含まれます)。

これを修正するには、遅いクエリを実際に調べて特定する必要があります。SQLServer Management Studioにも、たくさんのツールがあります。アクティビティモニター(ドキュメントはそれを見つけるのに役立ちます)は、CPUによって最も高価な最近のクエリを喜んで提供します-次に、それらを見て、エラーがどこにあるかを理解し始めることができます。きちんとした調査では、かなりの些細な問題ですが、前述の極端なCPU使用率につながる問題を簡単に修正できると思います。

しかし、要素として-あなたはとても上手に言います: "SQLを実行しているサーバーは非常に強力です"-私はここであなたの幻想に逆らうのは嫌ですが、これは2017年です。14GBのメモリを搭載した4コアマシンは「非常に強力」ではありません。それは本質的に「ローエンド」です。私はそのようなデスクトップでは動作しません。さて、私は「より大きなマシンを手に入れよう」と言っているのではなく、ハイエンドとして超ローエンドのスペックを自慢しないでください。 「非常に強力な」サーバーよりも強力なタブレットが市場に出回っています。ただし、サーバーの可用性に関する問題(メモリ不足、不十分IO帯域幅))は通常、CPUが低い(CPU待機中)になるため、これはこの特定の問題とは関係ありません。トラブルに遭遇したら、サーバーのスケーリングを検討してください。どのようにローエンドになるかを理解するには、ライセンスされたWindowsを必要とするSQL Serverを実行します。購入できる最小のWindows Serverライセンスは、16コア、4倍の数をカバーします。

1
TomTom