半夜被叫起優化一條 250 行、含 137 個 UNION ALL 的超長 INSERT ... SELECT。開發反映「以前快,現在慢」,且從未單獨測試 SELECT 效能。本文記錄現場急救與後續深度調優三階段策略。
0ah5a8dbk28fh,Plan Hash: 2746060288INSERT → LOAD TABLE CONVENTIONAL → UNION ALL → 137 個分支,每分支含多層 HASH JOIN OUTER、NESTED LOOPS-- 1. 確認最優計畫的 PHV(Plan Hash Value)
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('0ah5a8dbk28fh', NULL, NULL, 'ADVANCED'));
-- 2. 使用 Oracle 官方腳本綁定 SQL Profile
@?/rdbms/admin/coe_xfr_sql_profile.sql
-- 依提示輸入 SQL_ID、選擇最優 PHV(如 202K 那個)、生成並執行腳本
⚠ 決策依據: 非現場、無維護窗口、DML 回滾成本高 → **不 Kill、不硬解析、直接綁定已驗證的好計畫**。領採納,暫緩 Kill。
LAST_ANALYZED、NUM_ROWS、HISTOGRAM,確認是否過期導致誤判選擇率EXPLAIN PLAN,找出高成本分支共性(如缺索引、型別隱性轉換、笛卡爾積)WITH
base AS (SELECT ... FROM core_table WHERE ...),
agg1 AS (SELECT ... FROM base GROUP BY ...),
agg2 AS (SELECT ... FROM base GROUP BY ...)
SELECT ... FROM agg1 UNION ALL SELECT ... FROM agg2 ...;
將重複掃描提升為共用 CTE,減少 I/O。
ALTER SESSION ENABLE PARALLEL DML; -- Session 級開啟 PDML
INSERT /*+ PARALLEL(8) */ INTO target_table
SELECT ... FROM ... UNION ALL ...;
⚠ 必要條件: 目標表啟用 PARALLEL 屬性、無觸發器、無外鍵、Enterprise Edition。
ALTER SESSION ENABLE PARALLEL DML,否則 Hint 無效SQL Plan Baseline > SQL Profile > Hint,優先用 Baseline 固化穩定計畫後續: 下週拆解 137 分支、補統計資料、建 Baseline、開 PDML,預期從 4h 降至 30min 內。