DBAtlas · データベース運用アトラス

高い CPU 使用率

サーバーの CPU が張り付いている。まずデータベースが本当に消費しているのかを確認し、分岐をたどって根本原因に到達する: 実行計画の悪いクエリ、実行計画の性能低下、過剰な同時実行、または DB 以外のプロセス。

データベースが本当に CPU を消費しているか?

オペレーティングシステム側で、どのプロセスが CPU を消費しているかを確認する。負荷の大部分が DB プロセスにあるのか、それとも隣接するプロセス (バックアップ、ウイルス対策、別のアプリケーション) にあるのか? これにより調査は 2 つに分かれる。

-- OS side: top -o %CPU  (or: top -c)
-- DB-side verification:
SELECT ROUND(value,1) AS host_cpu_util_pct FROM v$sysmetric WHERE metric_name='Host CPU Utilization (%)' AND rownum=1;
  • はい、DB プロセスが CPU を消費している
  • いいえ、隣接するプロセス / バックアップジョブが消費している

負荷はどのように現れたか?

DB が CPU を消費している場合は、パターンを特定する: 少数の重いクエリが支配的なのか、変更の後に問題が突然始まったのか、それとも同時実行 / 接続の競合が多いのか?

  • 少数の重いクエリが CPU を消費している
  • 突然始まった。最近デプロイ / パラメータ変更があった
  • 接続が多い / 同時実行の競合

CPU を最も消費しているクエリを特定する

CPU の合計消費量で上位のクエリを取得する。次に、それぞれが 1 回あたり重い (実行計画が悪い) のか、1 回あたりは軽いが非常に頻繁に呼び出されているのかを判断する。

SELECT sql_id, executions, ROUND(cpu_time/1e6,1) AS cpu_sec, ROUND(cpu_time/GREATEST(executions,1)/1000,2) AS cpu_ms_per_exec, sql_text
FROM v$sql ORDER BY cpu_time DESC FETCH FIRST 10 ROWS ONLY;
  • 1 回あたりが重い。実行計画が悪い / フルスキャン
  • 1 回あたりは軽いが、非常に頻繁に呼び出される

根本原因: 実行計画の悪いクエリが CPU を消費している

少数のクエリが、フルスキャンや不適切な結合順序のために 1 回あたり過剰な CPU を消費している。それらの実行計画の修正が中心的な解決策である。

根本原因: 過剰な呼び出し頻度

クエリは個々には軽いが、毎秒数千回呼び出されており、それが CPU の合計コストの原因である。通常は N+1 パターン、またはキャッシュされていないホットパスである。

根本原因: 実行計画の性能低下 / 古い統計

昨日まではシステムは正常だった。デプロイ、パラメータ変更、データロードの後に CPU が急上昇した。オプティマイザがより悪い実行計画に切り替えた可能性がある。

根本原因: 高い同時実行性 / 接続の競合

個々のクエリは許容範囲だが、同時に実行されるセッションが多すぎる。CPU コア数を超えるアクティブセッションは、コンテキストスイッチとラッチ / スピンの競合を引き起こす。

根本原因: DB 以外のプロセスが CPU を消費している

CPU を消費しているのはデータベースではなく隣接するプロセスである: 同じマシン上のバックアップ / 圧縮ジョブ、ウイルススキャン、ログ転送ツール、または別のアプリケーション。

DBAtlas で開く →