10046 EVENT (Extended SQL Trace) 是診斷效能的利器,但鮮為人知的是:**啟用 Trace 會導致 Session 重新解析 SQL,可能產生不同執行計畫**,進而誤導效能分析。本文複現真實案例,展示綁定變數窺探與 Trace 互動導致計畫翻轉的完整過程。
T1:FLAG 欄位資料傾斜 (2000 個值各 ~25 筆,值 3000 有 10000 筆)T1_IDX(FLAG),已收集直方圖統計 (METHOD_OPT='FOR ALL INDEXED COLUMNS')
SELECT /*+ TESTSQL */ SUM(VALUE) FROM T1 WHERE FLAG = :V_FLAG;
ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 12';
-- 或
EXEC DBMS_MONITOR.SESSION_TRACE_ENABLE(WAITS=>TRUE, BINDS=>TRUE);
再次執行相同 SQL,**執行計畫變為 FULL TABLE SCAN**
-- 查看 Cursor 共享與解析狀態
SELECT SQL_ID, CHILD_NUMBER, PLAN_HASH_VALUE, PARSE_CALLS, EXECUTIONS,
OPTIMIZER_ENV_HASH_VALUE
FROM V$SQL WHERE SQL_TEXT LIKE '%TESTSQL%';
-- 查看綁定變數窺探歷史
SELECT * FROM V$SQL_BIND_CAPTURE WHERE SQL_ID = '...';
| 策略 | 做法 | 優缺點 |
|---|---|---|
| 使用 SQL Plan Baseline (11g+) | 固定優良計畫,避免計畫翻轉 | 需 Enterprise Edition + Tuning Pack |
| 關閉綁定變數窺探 | ALTER SESSION SET "_OPTIM_PEEK_USER_BINDS"=FALSE; (隱性參數) | 影響面廣,謹慎使用 |
| 使用 OPT_ESTIMATE / CARDINALITY Hint | 強制指導優化器 | 侵入性強,維護成本高 |
| 在 Trace 前先 WARM UP | 先執行幾次目標 SQL 使計畫穩定,再開啟 Trace | 簡單但不保證生產環境可行 |
| 使用 DBMS_XPLAN.DISPLAY_CURSOR | 事後從共享池取得實際執行計畫 (不需 Trace) | 推薦:無副作用、即時、準確 |