首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 硬解析執行步驟深度解析:59 次字典查詢、Consistent Gets、Physical Reads、軟解析對比

     編輯:Oracle 資料庫相關知識

硬解析 是 Oracle SQL 執行的最大效能殺手之一。首次執行查詢時,Oracle 需遍歷數十個數據字典表獲取元資料。本文揭示硬解析涉及的 16 張核心字典表、59 次查詢細節、Consistent Gets/Physical Reads 實測對比、Shared Pool LRU 淘汰影響、Session Cursor Cache 軟軟解析機制。

一、硬解析必經的 16 張核心字典表

字典表查詢次數用途常駐記憶體
ACCESS$1依賴物件對父物件的權限是
CCOL$10約束欄位具體資料是
CDEF$3約束定義資料是
COL$1表欄位具體資料否 (非永久駐留)
DEPENDENCY$1物件間依賴關係否
HIST_HEAD$12直方圖頭部資料是
HISTGRM$3直方圖規格是
ICOL$6索引欄位是
IND$, IND_STATS$1索引、索引統計資訊是
OBJ$8物件定義Dictionary Cache
OBJAUTH$2表授權是
SEG$7所有段映射是
SYN$1同義詞是
TAB$, TAB_STATS$1表、表統計資訊是
USER$2用戶定義是

總計:59 次查詢。標註「否」的表 (COL$, DEPENDENCY$) 不永久駐留 Dictionary Cache,可能觸發額外 Physical Read。

二、實測對比:硬解析 vs 軟解析 vs 全緩存

-- 測試查詢
SELECT * FROM ttest WHERE object_id = 1000;

-- 環境準備
SET AUTOTRACE TRACEONLY STATISTICS
場景Consistent GetsPhysical Reads解析類型CPU/閂鎖影響
首次執行 (冷啟動)230226硬解析佔用 1 CPU 核心,大量 Library Cache/Row Cache 閂鎖
ALTER SYSTEM FLUSH SHARED_POOL 後2986硬解析字典資訊部分仍在 Buffer Cache,但 Shared Pool 需重建
完全緩存後 (再次執行)2300軟解析零 Physical Read,最小 CPU/閂鎖

關鍵觀察

  • Physical Read ≠ 硬解析專屬:硬解析時字典塊若不在 Buffer Cache,會產生 Physical Read
  • 硬解析 CPU 密集:實時佔用一顆 CPU 核心,大量硬解析並發會導致 CPU 飽和、系統假死
  • Shared Pool LRU:字典快照會依 LRU 原則被淘汰,導致間歇性硬解析

三、三層解析機制對比

層級觸發條件開銷關鍵參數
硬解析Shared Pool 無匹配 Cursor (SQL 文本、綁定變數型別、環境不同)最高 (59+ 字典查詢、語法/語義檢查、優化器生成計畫)CURSOR_SHARING, SHARED_POOL_SIZE
軟解析Shared Pool 存在匹配 Cursor (Library Cache Hit)低 (僅語法/語義輕量檢查、綁定變數檢查)SESSION_CACHED_CURSORS
軟軟解析Session Cursor Cache 命中 (Client 端緩存 Cursor 狀態)極低 (繞過 Library Cache 查找,直接復用 Session 級 Cursor)SESSION_CACHED_CURSORS (預設 50,建議 200-500)

四、降低硬解析的五大實戰策略

  1. 使用綁定變數:WHERE id = :b1 而非 WHERE id = 1000,實現 Cursor Sharing
  2. 調大 Shared Pool:SHARED_POOL_SIZE 容納熱門 SQL 計畫,減少 LRU 淘汰
  3. 啟用 Session Cursor Cache:ALTER SESSION SET SESSION_CACHED_CURSORS=300 或 SPFILE 設定
  4. 固定執行計畫:DBMS_SHARED_POOL.KEEP 釘住核心 SQL,或使用 SQL Plan Baseline
  5. 避免 DDL 導致失效:統計資訊收集、索引重建、權限變更會使 Cursor 失效,安排在低峰期

五、監控硬解析的關鍵指標

-- 實例級硬解析率
SELECT 
  (1 - (session cursor cache hits) / (parse count (total))) * 100 AS hard_parse_pct
FROM v$sysstat
WHERE name IN ('session cursor cache hits', 'parse count (total)');

-- 高硬解析 SQL 識別
SELECT sql_text, parse_calls, executions, 
       ROUND(parse_calls/executions, 2) AS parse_per_exec
FROM v$sqlarea
WHERE executions > 0 AND parse_calls > executions * 1.5
ORDER BY parse_calls DESC;

硬解析是「必要之惡」,目標不是消除 (首次必經),而是通過綁定變數、Cursor Cache、Shared Pool 適度配置,將硬解析率控制在 < 5%,軟軟解析佔比 > 80%,構建高併發下的穩定解析引擎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved