SQLサーバーのCPU使用率が高い-クエリが遅い[終了]


11

MS SQL Serverは、CPUパワーの約95%を使用しています。

サーバー(ハードウェア)の再起動後、またはSQLサービスの再起動後、使用率は0%で、1〜3日かけてゆっくりと増加します。使用量によって異なります。

80%を超えると、すべてのクエリが非常に遅くなります。

私たちのウェブサイトは多くの大きなクエリを扱っているので、それらのいくつかは45-60秒かかります。再起動後(CPU使用率が80%未満)、同じクエリで11〜20秒かかります。


どうすれば修正できますか?アフィニティマスクでCPU使用率を調整できることをオンラインで読みましたが、アフィニティ設定が無効になっています。変更できません。これはプロセッサが1つしかないためですか?

クエリ自体にはたくさんのトリックがありますが、私たちのWebサイトとサービスは非常に大きく、変更するのは多すぎます。

それらのほとんどはすでにかなり最適化されています。


2秒しかかかりませんが、SQLサービスを再開し続けることができません。ユーザーが電話をかけてメッセージを録音できるアラームサービスがあるため、選択したグループが呼び出され、録音されたメッセージが聞こえます。

このシステムは何百人もの捜索救助チームによって使用されており、SQLサービスがアラーム中に再起動した場合、システムは終了し、呼び出した人には通知されません。


あちこち検索してみましたが、「アフィニティマスク」以外は変更できません。

現在のクエリを終了せずに、CPUキャッシュをクリアする方法が必要です...


SQL: Microsoft SQL Server 11.0.2100.60
OS: Windows Server 2012 x64
Processor: 2.30 GHz
RAM: 4.00 GB

コメントは詳細な議論のためのものではありません。この会話はチャットに移動しました
ポールホワイト9

回答:


7

これはロングショットですが、強制パラメーター化設定を確認することをお勧めします。パフォーマンスが悪いときに多数のクエリプランが表示される場合、クエリは期待どおりにキャッシュされておらず、クエリはキャッシュをスキャンして、すでに使用する予定があるかどうかを確認するのに長い時間がかかります。キャッシュをクリアするとこの問題が解決する場合は、強制パラメーター化設定の変更を検討することをお勧めします。以下を使用してキャッシュをクリアできます。

DBCC FREEPROCCACHE

キャッシュをクリアすると、次のようにして、強制パラメーター化設定が何であるかを確認できます。

SELECT name
     , is_parameterization_forced
  FROM sys.databases;

これはおそらくデフォルトの0に設定されています。彼らが望むなら、あなたはそれをtrueに設定することができます:

ALTER DATABASE [database_name] SET PARAMETERIZATION FORCED;

これは、最初に開発環境で行う必要があり、これが他の方法でデータベースに悪影響を及ぼすかどうかを確認します。以下を使用して元に戻すことができます:

ALTER DATABASE [database_name] SET PARAMETERIZATION SIMPLE;

5
プロシージャキャッシュを解放すると、実際にはCPUに大きなスパイクが発生する可能性があることに注意してください。これは、すべてのクエリが実行プランを再コンパイルする必要があるためです。
アーロンバートランド

18

アフィニティは「CPU使用率を調整する」ことはありません(たとえば、CPUの動作を減らします)。これにより、CPUをオフにする(おそらく同じマシンの別のインスタンスで使用できるようにする)か、CPUをI / Oのみで支援します。複数のCPUがあったとしても、前者を使用して目標を達成することはできません。また、CPU使用率が非常に高くなっている原因がわからないため、後者を推測することはできません。それは、非常に貧弱なインデックス作成、過度のコンパイル、豊富なスカラーUDF、I / Oスラッシングが原因である可能性があります。(そして、I / Oが原因である可能性があるのは、データベースが3 GB程度かそれ以上の場合、データがバッファープールメモリとの間で常にスワップされる必要があり、CPUの負荷がかかるためです。)

CPUキャッシュも、ダウンする必要がないうさぎの穴です。CPUキャッシュに問題があるため、CPUが95%でスラッシングしていることは間違いありません。

CPUプレッシャーの原因を絞り込むのに役立ち、ストアドプロシージャを使用していると想定して、Glenn Berryからのこの診断クエリを確認できます(ここから取得)-正しいデータベースのコンテキストで実行してください。

-- Top Cached SPs By Total Worker time (SQL Server 2012). 
-- Worker time relates to CPU cost  (Query 44) (SP Worker Time)

SELECT TOP (25) 
  p.name AS [SP Name], 
  qs.total_worker_time AS [TotalWorkerTime], 
  qs.total_worker_time/qs.execution_count AS [AvgWorkerTime], 
  qs.execution_count, 
  ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time, GETDATE()), 0) 
    AS [Calls/Second],
  qs.total_elapsed_time, 
  qs.total_elapsed_time/qs.execution_count AS [avg_elapsed_time], 
  qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK)
ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);

-- This helps you find the most expensive cached stored procedures from a CPU perspective
-- You should look at this if you see signs of CPU pressure

ストアドプロシージャを使用していない場合、John Samsonの次の例は、アドホッククエリ(ここから取得)を分離するのに役立ちます。

SELECT TOP (25)
    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 OPTION (RECOMPILE);

また、Adam Machanicのsp_WhoIsActiveを確認することもできます。これは、現在実行中のすべてのクエリをすばやく分析し、必要に応じて(たとえば、@sort_order = '[CPU] DESC')並べ替えることができるストアドプロシージャです。

ただし、特にこれが本当に捜索救助チームにとってミッションクリティカルである場合、私が最初に行うことは、より優れたハードウェアを購入することです。アプリケーションにサービスを提供するには、より多くのCPUとRAMが必要です。また、より優れた高可用性(クラスタリング、ミラーリング、可用性グループなど)も絶対に必要です。物理マシンを再起動することでアプリケーションが完全にオフラインになる理由はありません。その問題に対するより良い解決策があります。そして最後に、この「サーバー」には1つのディスクドライブしかないと思います。つまり、OS、SQL Serverデータファイル、ログファイル、tempdbなどからのすべてのI / Oはすべて、単一のコントローラーを経由して、単一のドライブで読み取り/書き込みアクティビティを共有します。より多くのディスクを取得します。可能な場合/場所でSSDを取得します。RAIDを使用して、I / Oを可能な限り分散するようにしてください。

つまり、問題にハードウェアを投入することだけが修正の一部になるわけではありません。過度のCPU使用率を引き起こしている原因を正確に特定し、使用しているハードウェアに関係なくこれらの問題に対処する必要があります。

その他のアイデアについては、このStackOverflowの質問もご覧ください。

/programming/945063/how-do-i-find-out-what-is-hammering-my-sql-server


0

次の提案は、実際のコードが見えないため、「暗闇の中でのショット」です。

まず、SPがカーソルを開いたままにしている可能性があります。カーソル、特にCloseとDeallocateについて読んでください。誰かが閉じている可能性がありますが、カーソルの割り当てを解除していません。アップグレードにより動作が変更された可能性があります。2012では、残りのカーソルの処理が2008 R2とは異なる場合があります。

2つ目は、クリアされないテーブルロックが存在する可能性があることです。繰り返しになりますが、わかりませんが、「トランザクションの開始」の後で誰かがグローバル一時テーブルを作成し、「トランザクションの終了」が実行されないか、ストアドプロシージャが失敗してロックされたままになります。 tempdbのスペースを占めるテーブル。

たまたまWinLinkを使っていますか?これについての何かは漠然とおなじみに聞こえます。


-4

パフォーマンスを向上させるには、memcachedのようなキャッシングメカニズムが必要です。


しかし、これでSQLサーバーのCPU使用率が変わることはありませんよね?それはウェブサイトでのクエリの速度を上げるだけで、他の誰かが同じテーブルのmemcachedの結果を使用している間にテーブルで何かが変更されるという問題があるかもしれませんよね?
Levi Johansen 2013年

@Leviクエリ結果を中間層のどこかにキャッシュすると、クエリはデータベースにヒットしません(キャッシュを更新する必要がある場合を除く)。
アーロンバートランド

1
Webサイトに誰もいないときにCPUも高い場合、Webレベルのものをキャッシュすることは明らかに役立ちません。Memcachedは優れたツールですが、有能な人が座って何もしていないはずのときにサーバーが何をしているかを調べるのに代わるものではありません。
TomTom 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.