dbms_spm包的使用(二)


dbms_spm包的使用

 

(二)将批量的sql执行计划都固定下来

 

在对emp表进行几次查询操作后,执行以下语句:

SQL> select sql_text,sql_id from v$sql where sql_text like '% emp %';

 

SQL_TEXT                                                                         SQL_ID

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

select * from emp where mgr=7839                                                 2xt4ug5mcccdn

select * from emp where ename='ALLEN'                                            4y6nkmx4dsr3q

select sql_text,sql_id from v$sql where sql_text like '% emp %'                  8x34a6v9dygmm

SELECT SQL_ID FROM V$SQL WHERE SQL_TEXT LIKE '% emp %'                           20215c0gn2wfw

select sql_id from v$sql where sql_text like '% emp %'                           1q2ahwwm5m1xm

 

如果我们希望将以上所有emp表相关的语句计划固定下来,则可以执行:

SQL> declare

  2    my_plans pls_integer;

  3  begin

  4    for i in (select sql_id from v$sql where sql_text like '% emp %') loop

  5      my_plans:=dbms_spm.load_plans_from_cursor_cache(sql_id=>i.sql_id);

  6    end loop;

  7  end;

  8  /

 

PL/SQL procedure successfully completed

 

查看在dba_sql_plan_baselines表中的记录:

SQL> select sql_handle,sql_text,plan_name from dba_sql_plan_baselines;

 

SQL_HANDLE                     SQL_TEXT                                                                         PLAN_NAME

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

SYS_SQL_1f5c56101761f5ee       SELECT SQL_ID FROM V$SQL WHERE SQL_TEXT LIKE '% emp %'                           SQL_PLAN_1yr2q20bq3xgfb73cade2

SYS_SQL_2a9b14f5ac58c943       select * from emp where ename='ALLEN'                                            SQL_PLAN_2p6snyqq5jka3d8a279cc

 

SYS_SQL_b4fcbe753d70a915       select * from emp where mgr=7839                                                 SQL_PLAN_b9z5yfnyr1a8pd8a279cc

 

SYS_SQL_d8c5743fa3353c9e       select * from v$sql where sql_text like '% emp %'                                SQL_PLAN_djjbn7yjmag4yb73cade2

 

 

类似地,如果希望将某个快照的sql全部固定下来,可以将上面for循环中的语句改为:

select sql_id from sys.wrh$_sqltext where snap_id=xxxx;

 

 

那么如何知道哪条语句的执行计划发生了修改呢?

 

先看以下两种场景:

 

(1)如果我们在emp表的mgr字段创建了索引,会出现以下结果:

SQL> create index idx_emp_mgr on emp(mgr);

 

Index created

 

SQL> select * from emp where mgr=7839;

 

      EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO

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

    7566.00 JONES      MANAGER    7839 1981/4/2      2975.00               20

    7698.00 BLAKE      MANAGER    7839 1981/5/1      2850.00               30

    7782.00 CLARK      MANAGER    7839 1981/6/9      2450.00               10

 

SQL> 

SQL> select sql_handle,sql_text,plan_name

  2  from dba_sql_plan_baselines t;

 

SQL_HANDLE                     SQL_TEXT                                                                         PLAN_NAME

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

SYS_SQL_1f5c56101761f5ee       SELECT SQL_ID FROM V$SQL WHERE SQL_TEXT LIKE '% emp %'                           SQL_PLAN_1yr2q20bq3xgfb73cade2

SYS_SQL_2a9b14f5ac58c943       select * from emp where ename='ALLEN'                                            SQL_PLAN_2p6snyqq5jka3d8a279cc

 

SYS_SQL_b4fcbe753d70a915       select * from emp where mgr=7839                                                 SQL_PLAN_b9z5yfnyr1a8p2237e0d1

 

SYS_SQL_b4fcbe753d70a915       select * from emp where mgr=7839                                                 SQL_PLAN_b9z5yfnyr1a8pd8a279cc

 

SYS_SQL_d8c5743fa3353c9e       select * from v$sql where sql_text like '% emp %'                                SQL_PLAN_djjbn7yjmag4yb73cade2

 

SQL>  select * from table(dbms_xplan.display_sql_plan_baseline(sql_handle=>'SYS_SQL_b4fcbe753d70a915',format=>'basic'));

 

PLAN_TABLE_OUTPUT

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

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

SQL handle: SYS_SQL_b4fcbe753d70a915

SQL text: select * from emp where mgr=7839

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

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

Plan name: SQL_PLAN_b9z5yfnyr1a8p2237e0d1         Plan id: 574087377

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

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

Plan hash value: 2059184959

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

| Id  | Operation                   | Name        |

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

|   0 | SELECT STATEMENT            |             |

|   1 |  TABLE ACCESS BY INDEX ROWID| EMP         |

|   2 |   INDEX RANGE SCAN          | IDX_EMP_MGR |

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

 

PLAN_TABLE_OUTPUT

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

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

Plan name: SQL_PLAN_b9z5yfnyr1a8pd8a279cc         Plan id: 3634526668

Enabled: YES     Fixed: NO      Accepted: YES     Origin: MANUAL-LOAD

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

Plan hash value: 3956160932

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

| Id  | Operation         | Name |

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

|   0 | SELECT STATEMENT  |      |

|   1 |  TABLE ACCESS FULL| EMP  |

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

 

34 rows selected

 

 

(2)如果表t上执行select object_id from t where object_id<10时原本存在索引。

创建基线后,删除索引。会有如下结果:

 

SQL> select sql_id,sql_text from v$sql where sql_text like 'select object_id from t where object_id<10%';

 

SQL_ID        SQL_TEXT

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

67dqwpb1nhyuk select object_id from t where object_id<10

 

SQL> declare

  2    my_plans pls_integer;

  3  begin

  4    my_plans:=dbms_spm.load_plans_from_cursor_cache(sql_id=>'67dqwpb1nhyuk');

  5    end;

  6  /

 

PL/SQL procedure successfully completed

SQL> select object_id from t where object_id<10;

 

8 rows selected.

 

 

Execution Plan

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

Plan hash value: 2498590897

 

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

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

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

|   0 | SELECT STATEMENT |                 |     8 |    40 |     2   (0)| 00:00:01 |

|*  1 |  INDEX RANGE SCAN| IDX_T_OBJECT_ID |     8 |    40 |     2   (0)| 00:00:01 |

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

 

Predicate Information (identified by operation id):

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

   1 - access("OBJECT_ID"<10)

 

Note

-----

   - SQL plan baseline "SQL_PLAN_5td0qnhnkk433f7fa6824" used for this statement

 

 

Statistics

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

         14  recursive calls

         13  db block gets

         12  consistent gets

          0  physical reads

       5064  redo size

        509  bytes sent via SQL*Net to client

        419  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          8  rows processed

 

SQL> set autot off

SQL> drop index idx_t_object_id;

 

Index dropped.

 

SQL> set autot trace

SQL> select object_id from t where object_id<10;

 

8 rows selected.

 

 

Execution Plan

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

Plan hash value: 1601196873

 

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

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

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

|   0 | SELECT STATEMENT  |      |     8 |    40 |   288   (1)| 00:00:04 |

|*  1 |  TABLE ACCESS FULL| T    |     8 |    40 |   288   (1)| 00:00:04 |

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

 

Predicate Information (identified by operation id):

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

 

   1 - filter("OBJECT_ID"<10)

 

 

Statistics

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

        209  recursive calls

         35  db block gets

       1067  consistent gets

       1035  physical reads

      14224  redo size

        509  bytes sent via SQL*Net to client

        419  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          5  sorts (memory)

          0  sorts (disk)

          8  rows processed

 

SQL> select sql_handle,sql_text,plan_name

  2  from dba_sql_plan_baselines t;

 

SQL_HANDLE                     SQL_TEXT                                                                         PLAN_NAME

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

SYS_SQL_1f5c56101761f5ee       SELECT SQL_ID FROM V$SQL WHERE SQL_TEXT LIKE '% emp %'                           SQL_PLAN_1yr2q20bq3xgfb73cade2

SYS_SQL_2a9b14f5ac58c943       select * from emp where ename='ALLEN'                                            SQL_PLAN_2p6snyqq5jka3d8a279cc

 

SYS_SQL_5cb416a429291063       select object_id from t where object_id<10                                       SQL_PLAN_5td0qnhnkk43394ecae5c


SYS_SQL_5cb416a429291063       select object_id from t where object_id<10                                       SQL_PLAN_5td0qnhnkk433f7fa6824

 

SYS_SQL_b4fcbe753d70a915       select * from emp where mgr=7839                                                 SQL_PLAN_b9z5yfnyr1a8p2237e0d1

 

SYS_SQL_b4fcbe753d70a915       select * from emp where mgr=7839                                                 SQL_PLAN_b9z5yfnyr1a8pd8a279cc

 

SYS_SQL_d8c5743fa3353c9e       select * from v$sql where sql_text like '% emp %'                                SQL_PLAN_djjbn7yjmag4yb73cade2

 

 

7 rows selected

 

SQL> 

SQL> SET SERVEROUTPUT ON

SQL> SET LONG 10000

SQL> DECLARE

  2    report clob;

  3  BEGIN

  4    report := DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(

  5    sql_handle => 'SYS_SQL_5cb416a429291063');

  6    DBMS_OUTPUT.PUT_LINE(report);

  7  END;

  8  /

 

 

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

                        Evolve SQL Plan Baseline Report

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

 

Inputs:

-------

  SQL_HANDLE = SYS_SQL_5cb416a429291063

  PLAN_NAME  = 

  TIME_LIMIT = DBMS_SPM.AUTO_LIMIT

  VERIFY     = YES

  COMMIT     = YES

 

Plan: SQL_PLAN_5td0qnhnkk43394ecae5c

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

  Plan was not verified.

  Plan was found to be same as the baseline plan.

  Plan was changed to an accepted plan.

由于索引删除,原有的使用索引的执行计划(基线)不能用了,只能使用新的执行计划

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

                                 Report Summary

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

Number of plans verified: 0

Number of plans accepted: 1

 

 

PL/SQL procedure successfully completed

 

SQL>  select * from table(dbms_xplan.display_sql_plan_baseline(sql_handle=>'SYS_SQL_5cb416a429291063',format=>'basic'));

 

PLAN_TABLE_OUTPUT

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

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

SQL handle: SYS_SQL_5cb416a429291063

SQL text: select object_id from t where object_id<10

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

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

Plan name: SQL_PLAN_5td0qnhnkk43394ecae5c         Plan id: 2498539100

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

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

Plan hash value: 1601196873

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

| Id  | Operation         | Name |

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

|   0 | SELECT STATEMENT  |      |

|   1 |  TABLE ACCESS FULL| T    |

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

 

PLAN_TABLE_OUTPUT

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

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

Plan name: SQL_PLAN_5td0qnhnkk433f7fa6824         Plan id: 4160383012

Enabled: YES     Fixed: NO      Accepted: YES     Origin: MANUAL-LOAD

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

Plan hash value: 1601196873

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

| Id  | Operation         | Name |

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

|   0 | SELECT STATEMENT  |      |

|   1 |  TABLE ACCESS FULL| T    |

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

与前面的SQL_PLAN_5td0qnhnkk433f7fa6824 实际执行计划相比可以看出,实际执行的是索引扫描,这里由于索引删除,不能捕获原执行计划了。

33 rows selected

 

 

通过前两个例子说明:在dba_sql_plan_baselines中根据sql_handle分组,有多条记录(多余一条记录)时,就说明语句的执行计划发生了修改或存在更优的计划。


============================================================


再次说明一下常用的语句:

(1)从缓存导入基线:

(3)declare
  my_plans pls_integer;
begin
  my_plans:=dbms_spm.load_plans_from_cursor_cache(sql_id=>'xxxxxxxxxx');
  end;
/
(2)根据plan_name或sql_handle查看执行计划:

 select * from table(dbms_xplan.display_sql_plan_baseline(plan_name=>'xxxxxxxxxxxxxx',format=>'basic'));

 select * from table(dbms_xplan.display_sql_plan_baseline(sql_handle=>'xxxxxxxxx',format=>'basic'));

(3)查看基线:

select sql_handle,sql_text,plan_name
from dba_sql_plan_baselines t;
(4)更新基线:

SET SERVEROUTPUT ON
SET LONG 10000
DECLARE
  report clob;
BEGIN
  report := DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(
  sql_handle => 'xxxxxxxxxx');
  DBMS_OUTPUT.PUT_LINE(report);
END;
/
(5)删除基线:

declare

  n pls_integer;

begin

  n:=dbms_spm.drop_sql_plan_baseline(plan_name=>'SQL_PLAN_djqgumq9ng3tada556d36');

  dbms_output.put_line(n);

end;

/

 



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26451536/viewspace-1175715/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26451536/viewspace-1175715/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值