Oracle版本 : 19.3.0
觀察一個 DB 執行SQL 會忽快忽慢, 通常會 建立 SQL Plan Baseline , 目的是 防止 Optimizer 隨統計資訊波動而「選錯計畫」,用來 穩定高頻、高價值 SQL 的效能行為
可以看出來 oracle 的建議
有出現兩個 plan hash , 一個是 0.047 秒, 另外一個是 3.923秒
這樣我們就知道 建立 Plan Baseline 是 3426048666 是 0.047 秒這一個 plan hash
BEGIN
DBMS_SQLTUNE.CREATE_SQL_PLAN_BASELINE(
task_name => 'TASK_111258', -- 實際 Tuning Task 名稱
owner_name => 'SYS', -- 建立該 Task 的使用者
plan_hash_value => 3426048666 -- 最快計畫的 hash 值
);
END;
/
*-----------------------------*
但建立 Plan Baseline 也不是萬無一失
以下操作會讓 Plan Baseline 中的 hash value 無法命中 , 而讓SQL執行爆走
Oracle 的 hash value 不是純邏輯計劃,而是對執行路徑中一連串 operation、成本估算、物件資訊的 hash 結果, 以下這些都會改變 hash 值
Index Rebuild : 可能會變, Oracle 會重新估算 I/O 路徑與成本
Gather Statistics : 高機率會變 , 當 num_rows, distinct_keys, clustering_factor 改變
改變 Optimizer 參數 : 可能會變, 如 _optimizer_cost_model、optimizer_mode
Gather Statistics : 高機率會變 , 當 num_rows, distinct_keys, clustering_factor 改變
改變 Optimizer 參數 : 可能會變, 如 _optimizer_cost_model、optimizer_mode
通常 有觀察到 index rebuild 後 SQL 反而不穩定, 可以再次執行 建立 Plan Baseline , 讓他固定
執行完後 可以查一下 是否有使用剛剛建立的 base line
SELECT sql_id, sql_plan_baseline, executions
FROM v$sql
WHERE sql_id = '6z7p1645q3gzga';
SELECT *
FROM dba_sql_plan_baselines
*-----------------------------*
企業生產上用法可以這樣
-- 在 rebuild 前,先記錄好 baseline plan hash
SELECT sql_handle, plan_name, plan_hash_value
FROM dba_sql_plan_baselines
WHERE sql_text LIKE '%SQL內容%';
-- Rebuild 後重新 evolve 舊 baseline
EXEC DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(sql_handle => '...', plan_name => '...');
-- 或從 Cursor Cache reload 新的好計畫
或者 重新在跑一次評估, 再次建立新的 baseline