DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE手工替换绑定执行计划

DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE手工替换绑定执行计划
使用SPM与sql profile一样功能:通过手工构造执行计划替换绑定

--创建测试表
SQL> create table tb1 as select * from dba_objects where object_id is not null;

Table created.


SQL> select count(1) from tb1;

  COUNT(1)
----------
     72533


SQL> update tb1 set object_id=66 where rownum<72533;

72532 rows updated.

SQL> commit;

Commit complete.

SQL> update tb1 set object_id=77 where object_id<>66;

1 row updated.

SQL> commit;

Commit complete.


SQL> create index idx_tb1_object_id on tb1(object_id);

Index created.

SQL> exec dbms_stats.gather_table_stats('AIKI','TB1',cascade=>true,method_opt=>'for columns object_id  size 1');

PL/SQL procedure successfully completed.

--77只有1条,执行计划为全表扫描,因为直方图未开导致CBO错误预估了结果集
SQL>  var aa number;
SQL>  exec :aa :=77;

PL/SQL procedure successfully completed.

SQL> select status from tb1 where object_id=:aa;

STATUS
-------
VALID

SQL> @all

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID  2hn00xzrv5t77, child number 6
-------------------------------------
select status from tb1 where object_id=:aa

Plan hash value: 3226679318

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |       |       |   290 (100)|          |
|*  1 |  TABLE ACCESS FULL| TB1  | 36267 |   283K|   290   (1)| 00:00:04 |

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
--------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / TB1@SEL$1

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OBJECT_ID"=:AA)

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - "STATUS"[VARCHAR2,7]


28 rows selected.

--手工构造正确的执行计划,并记录下sql_id和plan_hash_value

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  4jqbhqxt090yp, child number 0
-------------------------------------
select /*+ index(tb1(object_id)) */status from tb1 where object_id=:aa

Plan hash value: 455808360

-------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                   |       |       |   589 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| TB1               | 36267 |   283K|   589   (1)| 00:00:08 |
|*  2 |   INDEX RANGE SCAN          | IDX_TB1_OBJECT_ID | 36267 |       |    71   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / TB1@SEL$1
   2 - SEL$1 / TB1@SEL$1


--关键的执行步骤
--先导入全表扫的计划到baseline
DECLARE
k1 pls_integer;
begin
k1 := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
sql_id=>'2hn00xzrv5t77',
plan_hash_value=>3226679318,
fixed=>'NO',
enabled=>'YES');
end;
/

--手工构造执行计划,将前面运行的手工构造的SQL计划进行替换绑定
SQL>   show user
USER is "AIKI"
SQL> declare
  2  k1 pls_integer;
  3  begin
  4  k1:=DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
  5  sql_id=>'4jqbhqxt090yp',
  6  plan_hash_value=>455808360,
  7  sql_handle=>'SQL_e1f977ef3e9546c4',--原来不正确BASELINE
  8  fixed=>'NO',
  9  enabled=>'YES');
 10  end;
 11  /

PL/SQL procedure successfully completed.

--修改fix属性(也可以采用将没用的baseline,将其drop掉)
SQL> 
SQL>  declare
  2  k1 pls_integer;
  3  begin
  4  k1:=DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
  5  sql_handle=>'SQL_e1f977ef3e9546c4',
  6  plan_name=>'SQL_PLAN_f3ybrxwz9ajq4be29918e',
  7  attribute_name=>'FIXED',
  8  attribute_value=>'YES');
  9  end;
 10  /

PL/SQL procedure successfully completed.


--检查生效
SQL> show user
USER is "AIKI"
SQL>  var aa number;
SQL>  exec :aa :=77;

PL/SQL procedure successfully completed.

SQL> select status from tb1 where object_id=:aa;

STATUS
-------
VALID

SQL>  var aa number;
SQL>  exec :aa :=77;

PL/SQL procedure successfully completed.

SQL> select status from tb1 where object_id=:aa;

STATUS
-------
VALID

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  2hn00xzrv5t77, child number 6
-------------------------------------
select status from tb1 where object_id=:aa

Plan hash value: 455808360

-------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                   |       |       |   589 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| TB1               | 36267 |   283K|   589   (1)| 00:00:08 |
|*  2 |   INDEX RANGE SCAN          | IDX_TB1_OBJECT_ID | 36267 |       |    71   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / TB1@SEL$1
   2 - SEL$1 / TB1@SEL$1

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID"=:AA)

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - "STATUS"[VARCHAR2,7]
   2 - "TB1".ROWID[ROWID,10]

Note
-----
   - SQL plan baseline SQL_PLAN_f3ybrxwz9ajq4be29918e used for this statement


35 rows selected.

--可以看到人工构造的执行计划已经生效了;


你可能感兴趣的:(DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE手工替换绑定执行计划)