Oracle12c中SQL性能優化(SQL TUNING)新特性之自動重優化(automatic reoptimization)
Oracle12c中的自適應查詢優化有一系列不同特點組成。像自適應計劃(AdaptivePlans)功能可以在運行時修改執行計劃,但並不允許計劃中連接順序的改變。自動重優化基於先前執行和反饋到優化器信息的學習,因此,語句下次解析執行時將會生成一個較好的計劃。
1. 統計信息反饋(勢反饋)
勢反饋(Cardinalityfeedback)在Oracle11r2中被引進。當優化器產生一個執行計劃時,統計信息缺失、統計信息陳舊、復雜謂詞或復雜操作等也許會觸發優化器監視計劃中各個操作的勢。一旦執行完成,如果評估和實際勢之間差別較大,實際勢將會被存在SGA中以備今後使用,且該語句也被標作可重優化。該語句下次執行時會采用存儲的勢來進行重優化,以便采用較好的計劃。勢反饋是語句確定的,且實例重啟或共享池中的語句陳舊時會丟失。Oracle12c中,勢反饋已經重命名為統計信息反饋。
--註:
1) 統計信息反饋相關信息在SGA中作為V$SQL_REOPTIMIZATION_HINTS 視圖中的OPT_ESTIMATE hints 存儲。該視圖和hints未被歸檔。
1.1. 示例
下面的代碼創建一個管道表函數,通過它說明統計信息反饋
CONN test1/test@pdb1
-- 創建支持表函數的類型
DROP TYPE tp_tf_tab;
DROP TYPE tp_tf_row;
CREATE TYPE tp_tf_row AS OBJECT (
id NUMBER,
description VARCHAR2(50)
);
/
CREATE TYPE tp_tf_tab IS TABLE OF tp_tf_row;
/
-- 創建表函數.
CREATE OR REPLACE FUNCTION f_tab_pl (p_rows IN NUMBER) RETURN tp_tf_tabPIPELINED AS
BEGIN
FOR i IN 1 .. p_rows LOOP
PIPE ROW (tp_tf_row(i,‘Description for ‘ || i));
END LOOP;
RETURN;
END;
/
我們知道,優化器總是基於數據庫塊大小來評估管道表函數的勢,因此,我們希望得到該管道函數查詢勢的一個錯誤評估。下面的查詢返回10行數據,但優化器評估出了8168行,這顯然是錯誤的。
SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM TABLE(f_tab_pl(10));
SET LINESIZE 200 PAGESIZE 100
SELECT * FROM TABLE(DBMS_XPLAN.display_cursor(format => ‘allstatslast‘));
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------
SQL_ID 0ktmsgvczysxy, child number0
-------------------------------------
SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM TABLE(f_tab_pl(10))
Plan hash value: 822655197
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10 |00:00:00.01 |
| 1 | COLLECTION ITERATOR PICKLER FETCH|F_TAB_PL | 1 | 8168 | 10 |00:00:00.01 |
-------------------------------------------------------------------------------------------------
SQL>
檢查視圖列V$SQL.IS_REOPTIMIZABLE顯示優化器已經探測到了不正確的勢評估並把該語句標示為將被重新優化。
COLUMN sql_text FORMAT A50
COLUMN is_reoptimizable FORMAT A16
SELECT sql_text, is_reoptimizable
FROM v$sql
WHERE sql_text LIKE ‘%f_tab_pl%‘
AND sql_text NOT LIKE ‘%v$sql%‘;
SQL_TEXT IS_REOPTIMIZABLE
-------------------------------------------------- ----------------
SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM Y
TABLE(f_tab_pl(10))
SQL>
如果再次運行該語句,我們將看到更精確的一個勢評估,且有個註意部分告訴我們采用了統計信息反饋。同時,也註意到子遊標號也發生了改變。
SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM TABLE(f_tab_pl(10));
SET LINESIZE 200 PAGESIZE 100
SELECT * FROM TABLE(DBMS_XPLAN.display_cursor(format => ‘allstatslast‘));
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------
SQL_ID 0ktmsgvczysxy, child number1
-------------------------------------
SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM
TABLE(f_tab_pl(10))
Plan hash value: 822655197
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10 |00:00:00.01 |
| 1 | COLLECTION ITERATOR PICKLER FETCH|F_TAB_PL | 1 | 20 | 10 |00:00:00.01 |
-------------------------------------------------------------------------------------------------
Note
-----
- statistics feedback used forthis statement
SQL>
--註:
1) 11Rr2版本中,註意部分將會是"cardinality feedbackused for this statement"。
2) 文檔中也提到,勢的錯誤評估也會導致生成SQL計劃指令(SQLplan directives) ,但不要誤以為統計信息反饋被保留在SQL計劃指令中。我們可以通過如下語句查詢SQL計劃指令是否存在。
CONN sys@pdb1 AS SYSDBA
EXEC DBMS_SPD.flush_sql_plan_directive;
SET LINESIZE 200
COLUMN dir_id FORMAT A20
COLUMN owner FORMAT A10
COLUMN object_name FORMAT A10
COLUMN col_name FORMAT A10
SELECT TO_CHAR(d.directive_id) dir_id, o.owner, o.object_name,
o.subobject_name col_name,o.object_type, d.type, d.state, d.reason
FROM dba_sql_plan_directives d,dba_sql_plan_dir_objects o
WHERE d.directive_id=o.directive_id
AND o.owner = ‘TEST‘
ORDER BY 1,2,3,4,5;
no rows selected
SQL>
2. 性能反饋(Performance Feedback)
Oracle 11gR2引進了PARALLEL_DEGREE_POLICY初始化參數用以簡化並行查詢。該參數默認值為MANUAL,當被設置為AUTO時,能使並行度確定,語句排隊和內存內並行執行自動化。
Oracle 12cR1為該參數增加了ADAPTIVE設置,該值類似於AUTO,但包括了性能反饋。這種情況下,優化器決定語句是否並行運行和合適的並行度。當完成時,會對語句的實際性能和初始優化階段的評估性能進行對比。如果兩者間差別很大,則實際性能統計信息被存儲為統計信息反饋,且語句也被標為可重新優化的。當該語句下次被執行時,統計信息反饋會被用來選擇一個更合適的並行度(DOP)。
--註:
1) 從Oracle 11gR2向後,語句中的PARALLEL hint將導致系統自動選擇並行度,而不管PARALLEL_DEGREE_POLICY設置為什麽值。
3. 統計信息反饋和SQL計劃指令(相互作用)
該部分大多基於我對統計信息反饋的經驗推測。先前我們做測試的語句並不會保存為SQL計劃指令。統計信息反饋指示優化器已經做了不好的選擇,這些選擇一般是因為確定執行計劃時缺失重要的信息。統計信息反饋能被用於重優化,但它並不解決最初的問題。基本統計信息還是不具有代表性。
SQL計劃指令是“額外提示”,能阻止優化器在將來犯同樣的錯誤。在有些場景,自動重優化也會導致生成SQL計劃執行,但這並不包括統計信息反饋和性能反饋,而是執行動態采樣來解決短期內偏離問題,因此,不再需要統計信息反饋。
由於SQL計劃指令影響DBMS_STATS包未來收集統計信息的方式,因此,通過為基礎統計信息添加另外的信息(擴展統計信息),它有能力從根本上解決問題,從而使不再需要SQL計劃執行和統計信息反饋。一個需要統計信息反饋的場景也許會生成SQL計劃指令,但那並不意味著SQL計劃指令包含統計信息反饋的一個可保留版本。
當統計信息反饋和SQL計劃指令因勢錯誤評估而都被創建時,在兩者間有些很有意思的相互作用:
Ø 兩者都被在SGA中創建但SQL計劃指令還未被保留到SYSAUX表空間的場景中,統計信息反饋在重優化期間被使用,期間忽視SQL計劃指令的存在。
Ø 兩者都被創建但SQL計劃指令被保留到SYSAUX表空間的場景,SQL計劃指令在重優化期間被使用,統計信息反饋也可能被使用。
由於SQL計劃指令僅僅被周期性的保留,這意味著依賴於SQL語句第一次和第二次執行間時間的長短,最後的重優化可能是完全不同的,這導致結果的不可預測。
Oracle12c中SQL性能優化(SQL TUNING)新特性之自動重優化(automatic reoptimization)