Oracle 將解析後的 SQL 文字與執行計畫存放於 SGA 共享池。後續相同 SQL 可直接重用,避免重複解析,大幅降低 CPU 與閂爭用。
-- 兩條 SQL 僅字面值不同,無法共用
SELECT * FROM emp WHERE empno = 2000;
SELECT * FROM emp WHERE empno = 1000;
-- Java/C# 等應用層拼接
String sql = "SELECT * FROM emp WHERE empno = " + empno; // 每次產生不同文字
// 導致大量硬解析,共享池被擠佔,效能急遽下降
-- 使用預編譯語句
PreparedStatement ps = conn.prepareStatement(
"SELECT * FROM emp WHERE empno = ?");
ps.setInt(1, empno); // 同一 SQL 文字,不同值透過綁定傳遞
| 值 | 行為 |
|---|---|
EXACT(預設) | 嚴格匹配,僅完全相同共用 |
FORCE | 強制將字面值替換為系統產生綁定變數(:SYS_B_0),達到共用 |
SIMILAR(11g 棄用) | 類似 FORCE,但保留直方圖統計資訊優勢 |
ORA-07445 等 Bug。CURSOR_SHARING=EXACT。FORCE,配合 OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES 固定計畫,嚴密監控。共享 SQL 是 Oracle 高並發效能的基石。綁定變數是正道,CURSOR_SHARING 是有副作用的止痛藥。架構師應從源頭規範開發模式,而非依賴參數彌補設計缺陷。