oracle 稳定执行计划 spm 之一

os: centos 7.6
db: oracle 19.3

spm 的全称是 sql plan management,是 oracle 11g 中推出的一种主动稳定执行计划的手段,能够保证只有被验证过的执行计划才会被启用.

启动 spm

查看默认值

SQL> show parameter sql_plan;

NAME				     TYPE			      VALUE
------------------------------------ -------------------------------- ------------------------------

optimizer_capture_sql_plan_baselines boolean			      FALSE
optimizer_use_sql_plan_baselines     boolean			      TRUE

当前 session 中禁掉 spm,并同时开启自动捕获 sql plan baseline

SQL> select * from dba_sql_plan_baselines;

SQL> alter session set optimizer_use_sql_plan_baselines=false;
alter session set optimizer_capture_sql_plan_baselines=true;

执行 sql


SQL> select t0.*,t1.*
  from tmp_t0 t0,
       tmp_t1 t1
 where 1=1
   and t0.id=t1.id
;

SQL> select * from dba_sql_plan_baselines;

执行第一次,在 dba_sql_plan_baselines 没有看到任何记录

再执行一次

SQL> select t0.*,t1.*
  from tmp_t0 t0,
       tmp_t1 t1
 where 1=1
   and t0.id=t1.id
;

此时查看 dba_sql_plan_baselines 时已经有了相应的结果


SQL> set pagesize 200;
set linesize 200;
col sql_handle format a30;
col plan_name format a40;
col origin format a20;
col sql_text format a80;

SQL> select sql_handle,plan_name,origin,enabled,accepted,to_char(sql_text) sql_text from dba_sql_plan_baselines;

SQL_HANDLE		       PLAN_NAME				ORIGIN		     ENA ACC SQL_TEXT
------------------------------ ---------------------------------------- -------------------- --- --- --------------------------------------------------------------------------------
SQL_37a3d4db831fd717	       SQL_PLAN_3g8ynvf1jzpsr9e52db30		AUTO-CAPTURE	     YES YES select t0.*,t1.*
												       from tmp_t0 t0,
													    tmp_t1 t1
												      where 1=1
													and t0.id=t1.id

SQL_5c49de6d754a2305	       SQL_PLAN_5skfydpunn8s56a42112a		AUTO-CAPTURE	     YES YES select sql_handle,plan_name,origin,enabled,accepted,to_char(sql_text) from dba_s
												     ql_plan_baselines

SQL_9c0d7998b1d28680	       SQL_PLAN_9s3btm2sx51n0c51fbe40		AUTO-CAPTURE	     YES YES select * from dba_sql_plan_baselines


我们只需要关注 PLAN_NAME=SQL_PLAN_3g8ynvf1jzpsr9e52db30

恢复 spm 参数

SQL> alter session set optimizer_use_sql_plan_baselines=true;
alter session set optimizer_capture_sql_plan_baselines=false;

新开 session,测试 spm 的效果


explain plan
for 
select t0.*,t1.*
  from tmp_t0 t0,
       tmp_t1 t1
 where 1=1
   and t0.id=t1.id
;


select * from table(dbms_xplan.display())
;

Plan hash value: 3832590891
 
-----------------------------------------------------------------------------
| Id  | Operation          | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |        |     3 |    30 |     6   (0)| 00:00:01 |
|*  1 |  HASH JOIN         |        |     3 |    30 |     6   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| TMP_T0 |     3 |    18 |     3   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL| TMP_T1 |     3 |    12 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("T0"."ID"="T1"."ID")
 
Note
-----
   - SQL plan baseline "SQL_PLAN_3g8ynvf1jzpsr9e52db30" used for this statement

最后一行 SQL plan baseline “SQL_PLAN_3g8ynvf1jzpsr9e52db30” used for this statement
说明 spm 已经生效了.

如果有多条相同sql baseline,可以选择具体哪条 baseline

declare
 lv_tmp pls_integer;
begin
  lv_tmp:= dbms_spm.alter_sql_plan_baseline(
                        sql_handle => 'SQL_37a3d4db831fd717',
                        plan_name => 'SQL_PLAN_3g8ynvf1jzpsr9e52db30',
                        attribute_name => 'ENABLED',
                        attribute_value => 'YES' -- YES NO
                    );
  
end; 

参考:

你可能感兴趣的:(#,oracle,sql,plsql)