健康的資料庫伺服器在尖峰負載下 CPU 使用率應維持在 70%-90%。若閒置時仍高於 90%,代表 CPU 資源不足;若尖峰時極低,則可能存在 I/O 瓶頸、鎖競爭或執行計劃退化導致 CPU 無法被有效利用。本文將從作業系統層面、資料庫實例層面、會話與 SQL 層面三個維度,建構完整的 CPU 優化診斷鏈路。
sar -u 5 10 # 每 5 秒採樣 10 次,觀察 %user、%sys、%idle、%iowait
%iowait 持續高於 20% 提示 I/O 瓶頸而非 CPU 不足。
監視「處理器資訊」→「% 處理器時間」、「% 特權時間」、「% 使用者時間」。
查詢 V$SYSSTAT 關鍵指標:
SELECT name, value
FROM v$sysstat
WHERE name IN ('CPU used by this session',
'OS User level CPU time',
'OS System call CPU time');
判斷準則:若 Oracle CPU 佔比 > 90%,CPU 壓力源自資料庫本身;反之則需排查其他進程(備份軟體、監控代理、中介軟體等)。
SELECT s.sid, s.serial#, s.username, s.module,
st.value/100 AS cpu_centiseconds
FROM v$session s
JOIN v$sesstat st ON s.sid = st.sid
JOIN v$statname sn ON st.statistic# = sn.statistic#
WHERE sn.name = 'CPU used by this session'
AND s.type != 'BACKGROUND'
ORDER BY st.value DESC
FETCH FIRST 10 ROWS ONLY;
SELECT name, value
FROM v$sysstat
WHERE name IN ('parse time cpu', 'parse time elapsed', 'parse count (hard)');
parse time cpu:解析消耗的 CPU 時間。parse time elapsed:解析經過的牆鐘時間。wait time = parse time elapsed - parse time cpu:等待時間(鎖競爭、Library Cache 等待)。SELECT sql_text, parse_calls, executions
FROM v$sqlarea
WHERE parse_calls > executions * 1.5 -- 疑似未使用繫結變數
ORDER BY parse_calls DESC
FETCH FIRST 20 ROWS ONLY;
對策:
SESSION_CACHED_CURSORS(建議 50-200),減輕 Session Cursor Cache Miss 導致的軟解析開銷。CURSOR_SHARING = FORCE 作為緊急臨時方案(需評估副作用)。| 場景 | 特徵 | 對策 |
|---|---|---|
| 硬解析風暴 | parse count (hard) 激增、Library Cache: mutex X 等待 | 強制繫結變數、增加 SESSION_CACHED_CURSORS、檢查 Cursor Sharing |
| 低效執行計劃 | Full Table Scan、笛卡兒積、缺少索引、統計資訊過期 | 收集統計資訊、SQL Profile、SQL Plan Baseline、改寫 SQL |
| 鎖競爭 | enq: TX - row lock contention、高 parse time elapsed | 縮短交易、調整隔離級別、分區表減少熱塊 |
| PL/SQL 迴圈/遞迴 | 單一 Session CPU 佔用極高、無 I/O 等待 | 改用集合操作、BULK COLLECT/FORALL、避免 Row-by-row |
| 並行查詢濫用 | PX 進程眾多、OS %sys 高、CPU 排隊 | 限制 PARALLEL_DEGREE_POLICY、Resource Manager 管控 |
sar 輸出、核心 SQL 耗時。CPU 優化不是單一參數調整,而是自上而下(OS→Instance→Session→SQL)的系統性診斷。建立標準化的診斷腳本庫,將上述查詢封裝為日常巡檢與應急排查工具,才能在故障發生時快速定位、精準施策。