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