1. 程式人生 > >SQL Plan Management (2)

SQL Plan Management (2)

在之前的Blog 裡瞭解了Oracle 11g SQL Plan Management的理論,這篇Blog來演示一些具體的操作示例。

Oracle 11g 新特性 --SQL Plan Management 說明

官網說明:

Using SQL Plan Management

一. SPM 說明

與Oracle 9i 的outline和10g 的profile比,Oracle 11g的SPM相對更加的靈活。如,一條帶有繫結變數的SQL語句,最好的執行計劃會根據繫結變數的值而不同,11g以前的方法都無法解決這個問題。在11g中,與adaptive cursor sharing配合,SPM允許你同時接受多個執行計劃。執行時,根據不同的變數值,SPM會花費很少的運算從中選擇一條最合適的。 

SPM 相關的語句日誌、計劃歷史記錄和計劃基線都儲存在SQL 管理庫(SMB) 中,該庫還包含SQL概要檔案。SMB 是資料庫字典的一部分,儲存在SYSAUX 表空間中。預設情況下,SMB 的空間預算限制被設定為SYSAUX 大小的10%。但是,可以使用DBMS_SPM.CONFIGURE 過程配置SMB,將空間預算更改為介於1% 和50%之間的一個值。

如果SMB 空間超過了定義的百分比限制,則會向預警日誌中寫入警告。通過清除一些SQL管理物件(如SQL 計劃基線或SQL概要檔案)來增加SMB 空間限制、增加SYSAUX 大小或者減小SMB 大小之前,將按周生成警報。

SPM

相關引數:

注意事項:

(1)  使用多種方式控制執行計劃時:

  + Stored Outline(9i)存在時,它具有最高的優先順序。
  + 已經實施的SQL profile(10g)會被自動加入到SQL plan baseline中
  + STA(SQL Tuning Advisor) 會自動接收新的profile,意味著它會生成新的baseline。
(2)如果可能話,儘量移植到SPM,混合多種方式會變得複雜。

1.1 相關名詞說明

SQL Plan Management(SPM):oracle11g 中提供的新特性,用來更好地控制執行計劃。 
Plan History優化器生成的所有執行計劃的總稱。
SQL Plan Baseline

 Plan History裡那些被標記為“ACCEPTED”的執行計劃的總稱。
Plan Evolution把一條執行計劃從Plan History裡標記為“ACCEPTED”的過程。
SQL Management Base(SMB): 字典表裡儲存的執行計劃的總稱,包括Plan History,SQL Plan Baseline和SQL profile。

1.2 SPM的特點

1.2.1 與profile和outline相比,更加靈活的控制手段

(1)可以有很多的計劃被儲存下來,只有"ENABLED"並且"ACCEPTED"的執行計劃才可以被選擇。 
(2)允許有多個"ACCEPTED"的執行計劃,根據實際情況進行選擇。 
(3)可以用手工或者自動的方式,把執行計劃演化(evolve)為"ACCEPTED"。 還可以控制只讓效能更好的計劃被接受。
(4)允許設定"FIXED"的計劃。這樣其他的計劃將不會被選擇。

1.1.2 SPM使計劃真正的穩定

outline的缺點是太過死板,當資料量大幅度變化時無法做出相應的改變。 SQL proifle的缺點是,當資料量變化時,STA(SQL TuningAdvisor)會不可預知地去更改執行計劃。 而SPM則會提供幾個完整的plan供選擇。 

1.3 SPM的控制方式

SPM通過幾個標記來實現對執行計劃的控制:

(1)Enabled (控制活動):
  + YES (活動的,但不一定會被使用)
  + NO (可以理解為被標記刪除)
(2)Accepted(控制使用):
  + YES (只有 “Enabled” 並且“Accepted” 的計劃才會被選擇使用)
  + NO (如果是“Enabled” 那麼只有被evolve成“Accepted”才有可能被執行)
(3)Fixed(控制優先順序):
  + YES (如果是“Enabled”並且“Accepted”,會優先選擇這個計劃,這個計劃會被視為不需要改變的)
  + NO (普通的計劃,無需優先)
(4)Reproduced(有效性):
  + YES (優化器可以使用這個計劃)
  + NO (計劃無效,比如索引被刪除)

1.4 SPM如何捕捉(載入)執行計劃

1.4.1 自動捕捉

  1. 首先把OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES設定成TRUE。
  2. 從這個時刻開始,所有執行兩次以上的SQL語句會被觀測,執行計劃會進入Plan History。有個別例外的,參見note 788853.1。
  3. 生成的第一個執行計劃被標記為ENABLED並且是ACCEPTED,後續的執行計劃會被標記為ENABLED但不是ACCEPTED。

  4. 這時把OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES設定會FALSE,新的語句將不會建立Baseline。
  5. 需要注意的是,即使關閉了自動捕捉,針對存在baseline的SQL,由於ACS(自適應遊標共享)的作用,仍舊會有新的PLAN生成,新的Plan仍會進入Plan History,標記為ENABLED但不是ACCEPTED。 

1.4.2 批量匯入

匯入的baseline都會被自動標記為ACCEPTED,  Oralce提供六種方式把計劃匯入到sql plan baseline中:
(1)從 SQL Tuning Set STS 匯入:DBMS_SPM.LOAD_PLANS_FROM_SQLSET

(2)從Cursor Cache中裝載:DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE

(3)從Stored Outlines中匯入: DBMS_SPM.MIGRATE_STORED_OUTLINE
(4)從記憶體中存在的計劃中匯入:DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE;

(5)從staging table表中匯入:dbms_spm.create_stgtab_baseline

(6)通過staging table從另外一個系統中移植:
      DBMS_SPM.CREATE_STGTAB_BASELINE
      DBMS_SPM.PACK_STGTAB_BASELINE
      DBMS_SPM.UNPACK_STGTAB_BASELINE

1.5 執行計劃的選擇過程

在OPTIMIZER_USE_SQL_PLAN_BASELINES被設定成預設值TRUE,SQl Plan Baseline就會起作用。 

1. 首先,無論是否存在baseline,oracle都會正常進行硬解析或者軟解析,為SQL生成一個執行計劃。 由於ACS和bindpeeking的作用,存在baseline的SQL有可能在這時生成一個不同於baseline的執行計劃。

2. 如果baseline不存在,就按生成的計劃執行。如果baseline存在,那麼要檢視history裡是否有這個計劃,如果沒有,就將這個計劃插入,並標記為ENABLED,NON-ACCEPTED. 

3. 在baseline中檢視是否有FIXED的計劃存在,如果存在,執行FIXED的計劃,如果存在多個FIXED的計劃,根據統計資訊重新計算cost,選擇cost小的那個。

4. 如果FIXED的計劃不存在,就選擇ACCEPTED的計劃執行。 如果存在多個ACCEPTED的計劃,根據統計資訊重新計算cost,選擇cost小的那個。

注意:

這裡每次重新計算cost的代價不大,因為執行計劃是已知的,優化器不必遍歷所有的可能,只需根據演算法計算出已知計劃的cost便可。

1.6 執行計劃的演化(evolution)

執行計劃的演化指PlanHistory裡的執行計劃從NON-ACCEPTED,變成ACCEPTED的過程。如果上所述,由於ACS和Bind Peeking的作用,存在baseline的SQL有可能生成新的執行計劃,被儲存到Plan History中。 Oracle提供了API,通過自動或手工的方式,將一個計劃標記為ACCEPTED,這個計劃就會被後續的執行所選擇。 

使用DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE這個API來控制執行計劃的演化。語法:
DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE (
  sql_handle IN VARCHAR2 := NULL, --> NULL表示針對所有SQL
  plan_name  IN VARCHAR2 := NULL,
  time_limit IN INTEGER  := DBMS_SPM.AUTO_LIMIT,
  verify     IN VARCHAR2 := 'YES',
  commit     IN VARCHAR2 := 'YES' )
RETURN CLOB;

這裡由兩個標記控制:

(1)Verify:
  + YES (只有效能更好的計劃才會被演化)
  + NO (演化所有的計劃)
(2)Commit:
  + YES (直接演化)
  + NO (只生成報告)

這裡可以通過不同的排列組合,達到不同的效果:

(1)自動接收所有效能更好的執行計劃(Verify->YES, Commit->YES)
(2)自動接收所有新的執行計劃 (Verify->NO,Commit->YES)
(3)比較效能,生成報告,人工確認是否演化(Verify->NO, Commit->NO)

注意

對於效能的驗證的方式,oracle會去實際執行來比較buffer gets

1.7 修改已有的Baseline

通過DBMS_SPM.ALTER_SQL_PLAN_BASELINE來完成。 

語法:

DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
  sql_handle      IN VARCHAR2 := NULL,
  plan_name       IN VARCHAR2 := NULL,
  attribute_name  IN VARCHAR2,
  attribute_value IN VARCHAR2 )
RETURN PLS_INTEGER;

如把某個baseline 標記為FIXED:

SET SERVEROUT ON;
DECLARE
  x NUMBER;
BEGIN
  x := DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
    sql_handle      => '&&sql_handle',
    plan_name       => '&&plan_name',
    attribute_name  => 'FIXED',
    attribute_value => 'YES' );

END;
/

1.8 相關MOS 文件

Loading Hinted Execution Plans into SQLPlan Baseline. [ID 787692.1]

How to Use SQL Plan Management (SPM) -Example Usage (Doc ID 456518.1)
Plan Stability Features (Including SPM) Start Point (Doc ID 1359841.1) 
HOW TO LOAD SQL PLANS INTO SPM FROM AWR (Doc ID 789888.1)
Sql Plan Baseline Not always created (Doc ID 788853.1)
Transporting SQL PLAN Baselines from one database to another. (Doc ID 880485.1)

以上內容轉自:

二. SPM 示例

2.1 自動捕捉

OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES引數用來控制SPM的自動捕獲,該引數預設值為FALSE。當該引數設定為TRUE時,對於重複執行的SQL 都會被觀測,其對應的執行計劃也會被加入Plan History。生成的第一個執行計劃被標記為ENABLED並且是ACCEPTED,後續的執行計劃會被標記為ENABLED但不是ACCEPTED。 僅當在演化的過程中,效能最優的Plan (即標記為ACCEPTED)才會被新增到 SQL Plan baseline。

SQL> show parameteroptimizer_capture_sql_plan_baselines

NAME                                 TYPE                   VALUE

---------------------------------------------------------- ------------------------------

optimizer_capture_sql_plan_baselinesboolean                FALSE

SQL> alter system set optimizer_capture_sql_plan_baselines=true;

System altered.

SQL> show parameter optimizer_capture_sql_plan_baselines

NAME                                 TYPE                   VALUE

---------------------------------------------------------- ------------------------------

optimizer_capture_sql_plan_baselinesboolean                TRUE

SQL>

2.2 手工捕獲執行計劃

    SPM捕獲執行計劃有大致分自動捕獲和手工捕獲,手工捕獲又有6種方法,具體見1.4.2 小節。

注意:

手工裝載的執行計劃預設都會被標記為accepted。如果SQL Plan baseline已經存在,那麼裝載的執行計劃就會新增到對應的baseline裡,如果不存在,就建立一個baseline。

這裡演示最常用的從cursorcache中load plan。使用DBMS_SPM.load_plans_from_cursor_cache函式來完成,關於該函式的具體說明,請參考官方文件。

SQL> col plan_name for a35

SQL> col sql_handle for a30

SQL> col origin for a15

SQL> selectSQL_HANDLE,plan_name,origin,enabled,accepted,fixed from DBA_SQL_PLAN_BASELINES;

SQL_HANDLE                     PLAN_NAME                           ORIGIN          ENABLE ACCEPT FIXED

----------------------------------------------------------------- --------------- ------ ------ ------

SQL_a6f4c0adedb52ad0           SQL_PLAN_adx60prqvaaqhf8e55c8a      AUTO-CAPTURE    YES   YES    NO

SQL> DECLARE

 2    l_plans_loaded  PLS_INTEGER;

 3  BEGIN

 4    l_plans_loaded :=DBMS_SPM.load_plans_from_cursor_cache(sql_id => 'axpwqnq0454s9');

 5  END;

 6  /

PL/SQL procedure successfully completed.

SQL> selectSQL_HANDLE,plan_name,origin,enabled,accepted,fixed from DBA_SQL_PLAN_BASELINES;

SQL_HANDLE                     PLAN_NAME                           ORIGIN          ENABLE ACCEPT FIXED

----------------------------------------------------------------- --------------- ------ ------ ------

SQL_267afeb2e8216c2d           SQL_PLAN_2cyryqbn22v1da82c8876      MANUAL-LOAD     YES   YES    NO

SQL_a6f4c0adedb52ad0           SQL_PLAN_adx60prqvaaqhf8e55c8a      AUTO-CAPTURE    YES   YES    NO

SQL>

使用DBMS_SPM.load_plans_from_cursor_cache函式load 之後,在DBA_SQL_PLAN_BASELINES檢視中多了一條記錄,並且顯示該plan 是accepted狀態。

2.3 演化SQL Plan Baselines

    演化的過程就是把non-accepted 的plan 改成accepted的過程。 對於手工load的執行計劃,會自動執行evolving的過程,因此預設就是accepted,而對於自動裝載的執行計劃,就需要使用EVOLVE_SQL_PLAN_BASELINE函式來實現演化過程。

SQL> SET LONG 10000

SQL> SELECTDBMS_SPM.evolve_sql_plan_baseline(sql_handle => 'SQL_267afeb2e8216c2d')FROM   dual;

2.4 完整示例

--取消自動捕獲:

SQL> conn / as sysdba

Connected.

SQL> ALTER SYSTEM SET OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES=FALSE;

System altered.

--建立表並插入資料:

SQL> conn dave/dave

Connected.

SQL> CREATE TABLE spm_test_tab (

 2    id           NUMBER,

 3    description  VARCHAR2(50)

 4  );

Table created.

SQL> DECLARE

 2    TYPE t_tab IS TABLE OFspm_test_tab%ROWTYPE;

 3    l_tab t_tab := t_TAB();

 4  BEGIN

 5    FOR i IN 1 .. 10000 LOOP

 6      l_tab.extend;

 7      l_tab(l_tab.last).id := i;

 8     l_tab(l_tab.last).description := 'Description for ' || i;

 9    END LOOP;

 10   

 11   FORALL i IN l_tab.first .. l_tab.last

 12     INSERT INTO spm_test_tab VALUES l_tab(i);

 13   

 14   COMMIT;

 15  END;

 16  /

PL/SQL procedure successfully completed.

SQL> EXECDBMS_STATS.gather_table_stats(USER, 'SPM_TEST_TAB', cascade=>TRUE);

PL/SQL procedure successfully completed.

--使用非索引列進行查詢,這裡使用Table access full

SQL> set autot trace

SQL> SELECT description

 2  FROM   spm_test_tab

 3  WHERE  id = 99;

Execution Plan

----------------------------------------------------------

Plan hash value: 1107868462

----------------------------------------------------------------------------------

| Id | Operation         | Name         | Rows | Bytes | Cost (%CPU)| Time     |

----------------------------------------------------------------------------------

|   0| SELECT STATEMENT  |              |     1 |   25 |    13   (0)| 00:00:01 |

|*  1 | TABLE ACCESS FULL| SPM_TEST_TAB |    1 |    25 |    13  (0)| 00:00:01 |

----------------------------------------------------------------------------------

--獲取剛才查詢的SQL_ID:

SQL> SELECT sql_id

 2  FROM   v$sql

 3  WHERE  sql_text LIKE '%spm_test_tab%'

 4  AND    sql_text NOT LIKE'%dba_sql_plan_baselines%'

 5  AND    sql_text NOT LIKE '%EXPLAIN%';

SQL_ID

--------------------------

gat6z1bc6nc2d

--使用SQL_ID 從cursorcache中手工捕獲執行計劃:

SET SERVEROUTPUT ON

DECLARE

 l_plans_loaded  PLS_INTEGER;

BEGIN

 l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(

   sql_id => 'gat6z1bc6nc2d');

 DBMS_OUTPUT.put_line('Plans Loaded: ' || l_plans_loaded);

END;

/

Plans Loaded: 1

PL/SQL procedure successfully completed.

--使用DBA_SQL_PLAN_BASELINES檢視檢視SPM 資訊:

SQL> col sql_handle for a35

SQL> col plan_name for a35

SQL> set lin 120

SQL> SELECT sql_handle, plan_name,enabled, accepted

 2  FROM   dba_sql_plan_baselines

 3  WHERE  sql_text LIKE '%spm_test_tab%'

 4  AND    sql_text NOT LIKE'%dba_sql_plan_baselines%';

SQL_HANDLE                          PLAN_NAME                           ENABLE ACCEPT

---------------------------------------------------------------------- ------ ------

SQL_7b76323ad90440b9               SQL_PLAN_7qxjk7bch8h5tb65c37c8     YES    YES

--重新整理Share Pool,使下次SQL 執行時必須進行硬解析:

SQL> ALTER SYSTEM FLUSH SHARED_POOL;

System altered.

--建立索引,收集統計資訊,並查詢相同的SQL:

SQL> CREATE INDEX spm_test_tab_idx ONspm_test_tab(id);

Index created.

SQL> EXEC DBMS_STATS.gather_table_stats(USER,'SPM_TEST_TAB', cascade=>TRUE);

PL/SQL procedure successfully completed.

SQL> SELECT description

 2  FROM   spm_test_tab

 3  WHERE  id = 99;

Execution Plan

----------------------------------------------------------

Plan hash value: 1107868462

----------------------------------------------------------------------------------

| Id | Operation         | Name         | Rows | Bytes | Cost (%CPU)| Time     |

----------------------------------------------------------------------------------

|   0| SELECT STATEMENT  |              |     1 |   25 |    13   (0)| 00:00:01 |

|*  1 | TABLE ACCESS FULL| SPM_TEST_TAB |    1 |    25 |    13  (0)| 00:00:01 |

----------------------------------------------------------------------------------

這裡我們建立了索引,但是這裡還是走的全表掃描,這裡使用索引明顯才是最優的方案。

--檢視SPM 檢視:

SQL> SELECT sql_handle, plan_name,enabled, accepted

 2  FROM   dba_sql_plan_baselines

 3  WHERE  sql_handle = 'SQL_7b76323ad90440b9';

SQL_HANDLE                          PLAN_NAME                           ENABLE ACCEPT

---------------------------------------------------------------------- ------ ------

SQL_7b76323ad90440b9                SQL_PLAN_7qxjk7bch8h5tb65c37c8      YES   YES

SQL_7b76323ad90440b9               SQL_PLAN_7qxjk7bch8h5ted3324c0     YES    NO

通過baselines查詢的結果,可以看到我們的SQL 產生了2條執行計劃。但是我們認為最優的執行計劃並沒有被標記為ACCEPT,所以沒有使用。

--演化執行計劃: 演化就是將cost低的執行計劃標記為accept

SQL> SET LONG 10000

SQL> SELECTDBMS_SPM.evolve_sql_plan_baseline(sql_handle => 'SQL_7b76323ad90440b9') FROMdual;

DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(SQL_HANDLE=>'SQL_7B76323AD90440B9')

--------------------------------------------------------------------------------

-------------------------------------------------------------------------------

                        Evolve SQL PlanBaseline Report

-------------------------------------------------------------------------------

Inputs:

-------

 SQL_HANDLE = SQL_7b76323ad90440b9

 PLAN_NAME  =

 TIME_LIMIT = DBMS_SPM.AUTO_LIMIT

 VERIFY     = YES

DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(SQL_HANDLE=>'SQL_7B76323AD90440B9')

--------------------------------------------------------------------------------

 COMMIT     = YES

Plan:SQL_PLAN_7qxjk7bch8h5ted3324c0

------------------------------------

 Plan was verified: Time used .13 seconds.

 Plan passed performance criterion: 15.01 times better than baselineplan.

 Plan was changed to an accepted plan.

                            Baseline Plan      Test Plan       Stats Ratio

                            -------------      ---------       -----------

 Execution Status:             COMPLETE       COMPLETE

DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(SQL_HANDLE=>'SQL_7B76323AD90440B9')

--------------------------------------------------------------------------------

 Rows Processed:                      1              1

 Elapsed Time(ms):                 .376           .027             13.93

  CPUTime(ms):                      .333              0

 Buffer Gets:                        45              3                15

 Physical Read Requests:              0              0

 Physical Write Requests:             0              0

 Physical Read Bytes:                 0              0

 Physical Write Bytes:                0              0

 Executions:                          1              1

-------------------------------------------------------------------------------

DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(SQL_HANDLE=>'SQL_7B76323AD90440B9')

--------------------------------------------------------------------------------

                                 Report Summary

-------------------------------------------------------------------------------

Number of plans verified: 1

Number of plans accepted: 1

SQL>

--再次檢視DBA_SQL_PLAN_BASELINES檢視:

SQL> SELECT sql_handle, plan_name,enabled, accepted

 2  FROM   dba_sql_plan_baselines

 3  WHERE  sql_handle = 'SQL_7b76323ad90440b9';

SQL_HANDLE                          PLAN_NAME                           ENABLE ACCEPT

---------------------------------------------------------------------- ------ ------

SQL_7b76323ad90440b9                SQL_PLAN_7qxjk7bch8h5tb65c37c8      YES   YES

SQL_7b76323ad90440b9               SQL_PLAN_7qxjk7bch8h5ted3324c0     YES    YES

--再次執行SQL:

SQL> SELECT description

 2  FROM   spm_test_tab

 3  WHERE  id = 99;

Execution Plan

----------------------------------------------------------

Plan hash value: 3121206333

------------------------------------------------------------------------------------------------

| Id | Operation                   |Name             | Rows  | Bytes | Cost (%CPU)| Time     |

------------------------------------------------------------------------------------------------

|   0| SELECT STATEMENT            |                  |     1 |   25 |     2   (0)| 00:00:01 |

|   1|  TABLE ACCESS BY INDEX ROWID|SPM_TEST_TAB     |     1 |   25 |     2   (0)| 00:00:01 |

|*  2 |  INDEX RANGE SCAN          |SPM_TEST_TAB_IDX |     1 |       |    1   (0)| 00:00:01 |

------------------------------------------------------------------------------------------------

這次正確的使用了索引。 因為只有標記為ENABLE和 ACCEPT的plan 才可以被使用。

2.5 修改 Plan Baselines

通過ALTER_SQL_PLAN_BASELINE函式可以修改執行計劃的屬性,具體修改的選項如下:

(1)  enabled (YES/NO) : If YES, the plan is available for theoptimizer if it is also marked as accepted.

(2)  fixed (YES/NO) : If YES, the SQL plan baseline will not evolveover time. Fixed plans are used in preference to non-fixed plans.

(3)  autopurge (YES/NO) : If YES, the SQL plan baseline is purgedautomatically if it is not used for a period of time.

(4)  plan_name : Used to amend the SQL plan name, up to a maximum of30 character.

(5)  description : Used to amend the SQL plan description, up to amaximum of 30 character.

下面示例將我們2.4 節中的第一個走全表掃描的執行計劃標記為fixed。 標記為fixed的執行計劃會被優先使用。

DECLARE

 l_plans_altered  PLS_INTEGER;

BEGIN

 l_plans_altered := DBMS_SPM.alter_sql_plan_baseline(

    sql_handle      => 'SQL_7b76323ad90440b9',

    plan_name       => 'SQL_PLAN_7qxjk7bch8h5tb65c37c8',

   attribute_name  => 'fixed',

   attribute_value => 'YES');

 DBMS_OUTPUT.put_line('Plans Altered: ' || l_plans_altered);

END;

/

Plans Altered: 1

PL/SQL procedure successfully completed.

--驗證:

SQL> set lin 180

SQL> col sql_handle for a25

SQL> col plan_name for a35

SQL> col origin for a15

SQL> selectSQL_HANDLE,plan_name,origin,enabled,accepted,fixed from DBA_SQL_PLAN_BASELINES;

SQL_HANDLE                PLAN_NAME                           ORIGIN          ENABLE ACCEPT FIXED

------------------------------------------------------------ --------------- ------ ------ ------

SQL_267afeb2e8216c2d      SQL_PLAN_2cyryqbn22v1da82c8876      MANUAL-LOAD     YES   YES    NO

SQL_496b0b4abd8a2948      SQL_PLAN_4kusb9aysnaa865d30abd      AUTO-CAPTURE    YES   YES    NO

SQL_5f081cda0133e385      SQL_PLAN_5y20wv80m7sw5391601ca      AUTO-CAPTURE    YES   YES    NO

SQL_7b76323ad90440b9      SQL_PLAN_7qxjk7bch8h5tb65c37c8      MANUAL-LOAD     YES   YES    YES

SQL_7b76323ad90440b9      SQL_PLAN_7qxjk7bch8h5ted3324c0      AUTO-CAPTURE    YES   YES    NO

SQL_a6f4c0adedb52ad0      SQL_PLAN_adx60prqvaaqhf8e55c8a      AUTO-CAPTURE    YES   YES    NO

SQL_f88491799a8f900b      SQL_PLAN_gj14jg6d8z40ba052f708      AUTO-CAPTURE    YES   YES    NO

--再次檢視我們之前的SQL:

SQL> SELECT description

 2  FROM   spm_test_tab

 3  WHERE  id = 99;

Execution Plan

----------------------------------------------------------

Plan hash value: 1107868462

----------------------------------------------------------------------------------

| Id | Operation         | Name         | Rows | Bytes | Cost (%CPU)| Time     |

----------------------------------------------------------------------------------

|   0| SELECT STATEMENT  |              |     1 |   25 |    13   (0)| 00:00:01 |

|*  1 | TABLE ACCESS FULL| SPM_TEST_TAB |    1 |    25 |    13  (0)| 00:00:01 |

----------------------------------------------------------------------------------

--這裡已經走了全表掃描,根據2.4的示例,這裡走索引會更優,但因為我們將走全表掃描的執行計劃設定為fixed,所以優先使用這個執行計劃。

2.6 顯示SQL Plan Baselines

我們可以查詢DBA_SQL_PLAN_BASELINES檢視來獲取baselines的資訊,也可以通過DBMS_XPLAN包來獲取。 DISPLAY_SQL_PLAN_BASELINE函式會將plan 按一定格式進行輸入,這裡格式可以選擇:BASIC, TYPICAL 和ALL,預設使用TYPICAL。

示例如下:

SET LONG 10000

SELECT * FROM  

TABLE(DBMS_XPLAN.display_sql_plan_baseline(plan_name=>'SQL_PLAN_7qxjk7bch8h5ted3324c0'));

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------

SQL handle: SQL_7b76323ad90440b9

SQL text: SELECT description FROM   spm_test_tab WHERE  id = 99

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

Plan name:SQL_PLAN_7qxjk7bch8h5ted3324c0        Plan id: 3979551936

Enabled: YES     Fixed: NO      Accepted: YES     Origin: AUTO-CAPTURE

--------------------------------------------------------------------------------

PLAN_TABLE_OUTPUT

----------------------------------------------------------------------------------------------------

Plan hash value: 3121206333

------------------------------------------------------------------------------------------------

| Id | Operation                   |Name             | Rows  | Bytes | Cost (%CPU)| Time     |

------------------------------------------------------------------------------------------------

|   0| SELECT STATEMENT            |                  |     1 |   25 |     2   (0)| 00:00:01 |

|   1|  TABLE ACCESS BY INDEX ROWID|SPM_TEST_TAB     |     1 |   25 |     2   (0)| 00:00:01 |

|*  2|   INDEX RANGE SCAN          | SPM_TEST_TAB_IDX |     1 |      |     1   (0)| 00:00:01 |

------------------------------------------------------------------------------------------------

Predicate Information (identified byoperation id):

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------

   2- access("ID"=99)

25 rows selected.

2.7 設定SQL Management Base

SQL Management Plan的資料存在在SYSAUX表空間下面,存放的資料包括SQL Plan baselines,statement logs,plan histories 和SQL Profiles。 SMB 能分配的磁碟空間由如下2個屬性控制。 可以使用DBMS_SPM.CONFIGURE過程來進行修改:

(1) space_budget_percent (default10) : Maximum size as a percentage of SYSAUX space.Allowable values 1-50.

(2)  plan_retention_weeks (default 53) : Number of weeks unusedplans are retained before being purged. Allowable values 5-523 weeks.

SQL> col parameter_name for a25

SQL> SELECT parameter_name, parameter_valueFROM   dba_sql_management_config;

PARAMETER_NAME            PARAMETER_VALUE

------------------------- ---------------

SPACE_BUDGET_PERCENT                   10

PLAN_RETENTION_WEEKS                   53

--修改這2個屬性:

SQL> BEGIN

 2   DBMS_SPM.configure('space_budget_percent', 11);

 3   DBMS_SPM.configure('plan_retention_weeks', 54);

 4  END;

 5  /

PL/SQL procedure successfully completed.

--驗證:

SQL> SELECT parameter_name,parameter_value FROM  dba_sql_management_config;

PARAMETER_NAME            PARAMETER_VALUE

------------------------- ---------------

SPACE_BUDGET_PERCENT                   11

PLAN_RETENTION_WEEKS                   54

2.8 遷移SQL Plan Baselines

可以使用DBMS_SPM 包將SQLPlan baselines在不同資料庫之間進行遷移。 具體的操作步驟如下。

2.8.1 在source database 建立登臺表(staging table)

BEGIN

 DBMS_SPM.CREATE_STGTAB_BASELINE(

   table_name      =>'spm_stageing_tab',

   table_owner     => 'DAVE',

   tablespace_name => 'USERS');

END;

/

2.8.2  將SQL Planbaselines 匯入staging table

    使用PACK_STGTAB_BASELINE函式可以實現這個功能,該函式有一些引數,具體參考官方文件。 這裡示例將所有SQL Plan Baselines匯入staging table。

SET SERVEROUTPUT ON

DECLARE

 l_plans_packed  PLS_INTEGER;

BEGIN

 l_plans_packed := DBMS_SPM.pack_stgtab_baseline(

   table_name      =>'spm_stageing_tab',

   table_owner     => 'DAVE');

 DBMS_OUTPUT.put_line('Plans Packed: ' || l_plans_packed);

END;

/

SQL>

2.8.3 將staging table 傳輸到目標庫

    這裡可以使用expdp/impdp 實現。 不多說。

2.8.4 將staging table匯入目標庫

    使用UNPACK_STGTAB_BASELINE函式實現這個功能,同樣有一些引數設定,這裡演示匯入所有SQL PLAN BASELINES.

SET SERVEROUTPUT ON

DECLARE

 l_plans_unpacked  PLS_INTEGER;

BEGIN

 l_plans_unpacked := DBMS_SPM.unpack_stgtab_baseline(

   table_name      =>'spm_stageing_tab',

   table_owner     => 'DAVE',

   creator         => 'DAVE');

 DBMS_OUTPUT.put_line('Plans Unpacked: ' || l_plans_unpacked);

END;

/

2.9 刪除Plans 和 Baselines

DROP_SQL_PLAN_BASELINE函式可以從baselines中drop 某個執行的執行計劃,如果不執行plan name,那麼會drop 所有的plan。即drop了baseline。

SET SERVEROUTPUT ON

DECLARE

 l_plans_dropped  PLS_INTEGER;

BEGIN

 l_plans_dropped := DBMS_SPM.drop_sql_plan_baseline (

   sql_handle => 'SQL_7b76323ad90440b9',

   plan_name  => NULL);

 DBMS_OUTPUT.put_line(l_plans_dropped);

END;


相關推薦

SQL Plan Management 2

在之前的Blog 裡瞭解了Oracle 11g SQL Plan Management的理論,這篇Blog來演示一些具體的操作示例。 Oracle 11g 新特性 --SQL Plan Management 說明 官網說明: Using SQL Plan Management 一. SPM

MySQL階段二——sql語句基礎2

mysql數據查詢操作 01.創建數據表 (02-05練習) (連接查詢練習使用) 02.單表查詢 03.分組統計 04.嵌套查詢 05.集合查詢 06.連接查詢 07.連接查詢與集合查詢的不同 數據查詢操作01.創建數據表 1)創建Student表 (2)創建Course表

EXPLAIN sql優化方法2 Using temporary ; Using filesort

它的 In 默認 const join 產生 收藏 -c 意思 優化GROUP BY語句 默認情況下,MySQL對所有GROUP BY col1,col2...的字段進行排序。這與在查詢中指定ORDER BY col1,col2...類似。因此,如果顯式包括一個包含

T-SQL執行內幕2——Tasks、Workers、Threads、Scheduler、Sessions、Connections、Requests

本文屬於SQL Server T-SQL執行內幕系列     接上文:T-SQL執行內幕(1)——簡介     本節以介紹一些基礎的但又容易混淆的概念。包括:Tasks、Workers、Threads

SQL SERVER 索引2——設計原則

       索引有助於我們提高系統的效能,提升查詢效率,但是如果索引設計的不夠合理,可能會適得其反,讓我們的系統更加緩慢,查詢效率下降,所以本次介紹一下索引的設計原則。        資料表的選擇:  

SQL盲注2

時間延遲 測試SQL注入漏洞時,會發現某一潛在漏洞難以確定,主要原因是Web應用沒有顯示任何錯誤,因而無法檢索任何資料。這種情況下,可以考慮向資料庫注入時間延遲。MSSQL伺服器有一條內建命令waitfor delay 'hours:minutes:seconds' http://127.0.0.1

SQL—訪問操作2

  上一篇介紹了資料訪問操作的兩種方法,接下來把剩下兩個操作簡單介紹一下:   ExecuteNonQuery()的操作:對資料庫進行增加、修改、刪除 返回型別是 int  代表受影響的行數 返回的結果如果是 0 代表操作失敗 受影響的行數為 0 , 如果大於 0 則新增成功 /// <summary

SQL面試題2

問題描述: 本題用到下面三個關係表: CARD 借書卡。 CNO 卡號,NAME 姓名,CLASS 班級 BOOKS 圖書。 BNO 書號,BNAME 書名,AUTHOR 作者,PRICE 單價,QUANTITY 庫存冊數 BORROW 借書記錄。 CNO 借書卡號

SQL語句學習2之基本查詢、排序、聚合函式、分組查詢

一、 基本查詢 1. 欄位(列)控制 1) 查詢所有列  SELECT * FROM 表名;  SELECT * FROM emp;  --> 其中“*”表示查詢所有列 2) 查詢指定列  SELECT 列1 [, 列2, ... 列N] FROM 表名;  SEL

SQL Server2005雜談2:公用表表達式CTE的遞迴呼叫

本文為原創,如需轉載,請註明作者和出處,謝謝! 上一篇:SQL Server2005雜談(1):使用公用表表達式(CTE)簡化巢狀SQL 先看如下一個資料表(t_tree):     上圖顯示了一

MySQL5.7效能優化系列——SQL語句優化2——子查詢-派生表-檢視--概述

章節內容: 使用Semi-join連線優化子查詢、派生表、檢視 使用Materialization優化子查詢 優化派生表、檢視 使用Exist 策略優化子查詢 概述 in或者any子查詢 MySQL查詢優化器具有不同的策略來評估子查詢。對於IN(

防禦SQL注入方法2-過濾特殊字元

防禦SQL注入的一個重要方法是對使用者輸入進行過濾,PHP中mysqli_real_escape_string(connection,escapestring)和mysqli_escape_string(connection,escapestring)函式就是對

Oracle SPMSQL Plan Management介紹及演示SQL

Oracle優化器輔助手段的發展 Oracle 8:hint Oracle 8i&9: stored outline Oracle 10: sql profile Oracle 11: sql plan manangement 優化器可能選擇

Oracle 11g 針對SQL效能的新特性- SQL Plan Management

簡介 在Oracle 11g之前,執行計劃一直是作為“執行時”生成的物件存在。雖然oracle提供了一些方法去指導它的生成,但Oracle一直沒有試圖去儲存完整的執行計劃。 從11g開始,執行計劃就可以作為一類資源被儲存下來,允許特定SQL語句只能選擇“已知”的執行計劃。  同其他方法相比,SPM更加的靈活。

SQL Server 運行計劃操作符具體解釋2——串聯(Concatenation )

-s 而且 article font order close 格式 聚集索引 content 本文接上文:SQL Server 運行計劃操作符具體解釋(1)——斷言(Assert)前言: 依據計劃。本文開始講述另外一個操作符串聯(Concatenation)。讀者能夠依

SQL從零到迅速精通【實用函數2

表的操作 deny 獲取 拒絕 分享 子字符串 evo sci ever 1.對查詢結果進行排序 查詢stu_info表中所有學生信息,並按照成績由高到底進行排序,輸入語句如下。 SELECT * FROM stu_info ORDER BY s_score DESC;

常見的SQL命令2

oracle sql 語句 創建學生情況表:student create table student(st_class CHAR(8),st_no CHAR(10) NOT NULL,st_name CHAR(8) NOT NULL,st_sex CHAR(2),st

SQL Server橫向擴展:設計,實現與維護2- 分布式分區視圖

做的 img attach one 遠程 cnblogs ole out 不同的 為了使得朋友們對分布式分區視圖有個概念,也為了方便後面的內容展開,我們先看看下面一個圖: 講述分布式分區視圖之前,很有必要將之與我們常常熟悉的分區表和索引

全廢話SQL Server統計信息2——統計信息基礎

position amp 要去 fault href 過程 字符串 最大 實用 接上文:http://blog.csdn.net/dba_huangzj/article/details/52835958我想在大地上畫滿窗子,

MySQL常用操作2MySQL用戶管理、常用sql語句、 MySQL數據庫備份恢復

MySQL用戶管理 MySQL用戶管理創建一個普通用戶並且授權1.grant all on *.* to 'user1' identified by 'passwd';grant all on *.* to 'user1' iden