Oracle 固定执行计划-使用SPM(Sql Plan Management)固定执行计划

摘要:
11g中,Oracle提供了SPM。通过这个特性,可以考虑让Oracle自动去判断某个SQL的新的执行计划是否更加合理,只有在新的执行计划比原来的执行计划更好才会被使用,从而保护了执行计划的稳定性和SQL语句的执行效率。可以考虑手工捕获和自动捕获两种方式,这里我们采用手工捕获。
固定执行计划-使用SPM(Sql Plan Management)固定执行计划

转载自:http://www.lunar2013.com/2016/01/固定执行计划-使用spm%EF%BC%88sql-plan-management%EF%BC%89固定执行计划.html

.
固定执行计划-使用SQL Tuning Advisor
固定执行计划-手工指定PLAN OUTLINE
固定执行计划-手工指定索引名称的方式
固定执行计划-使用coe_xfr_sql_profile固定执行计划
固定执行计划-使用SPM(Sql Plan Management)固定执行计划
.

在Oracle 11g前,我们可以借助存储大纲(Stored Outline)和SQL Profile来帮助我们固定某个SQL语句的执行计划。
11g中,Oracle 提供了SPM(Sql Plan Management)。
通过这个特性,可以考虑让Oracle自动去判断某个SQL的新的执行计划是否更加合理(成本更低),只有在新的执行计划比原来的执行计划更好才会被使用,从而保护了执行计划的稳定性和SQL语句的执行效率。
可以考虑手工捕获和自动捕获两种方式,这里我们采用手工捕获(11.2的缺省设置是非自动捕获)。
首先查看当前为禁止自动捕获的状态:

SYS@lunardb>show parameter optimizer_capture_sql_plan_baselines
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_capture_sql_plan_baselines boolean FALSE
SYS@lunardb>

当前SPM中没有内容:

LUNAR@lunardb>selectsignature,sql_handle,plan_name,origin,enabled,accepted,autopurge from dba_sql_plan_baselines;
no rows selected
Elapsed: 00:00:00.00
LUNAR@lunardb>

手工加载一个SQL到SPM中:

LUNAR@lunardb>declare
2 l_plans_loaded PLS_INTEGER;
3 begin
4 l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(sql_id => '&sql_id');
5 DBMS_OUTPUT.put_line('Plans Loaded: '|| l_plans_loaded);
6 END;
7 /
Enter value forsql_id: bjgduva68mbqm
old 4: l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(sql_id => '&sql_id');
new 4: l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(sql_id => 'bjgduva68mbqm');
Plans Loaded: 1
PL/SQLprocedure successfully completed.
Elapsed: 00:00:00.21
LUNAR@lunardb>
LUNAR@lunardb>selectsignature,sql_handle,plan_name,origin,enabled,accepted,autopurge from dba_sql_plan_baselines;
SIGNATURE SQL_HANDLE PLAN_NAME ORIGIN ENA ACC AUT
---------------- ------------------------------ ------------------------------ -------------- --- --- ---
6.5941520220E+17 SQL_0926b6a1f69f6f5c SQL_PLAN_0k9pqn7v9yvuw02b73393 MANUAL-LOAD YES YES YES
Elapsed: 00:00:00.01
LUNAR@lunardb>

由于上一个测试,我们已经有了正确的执行计划,即:

LUNAR@lunardb>select* from table(dbms_xplan.display_cursor(sql_id=>'bjgduva68mbqm')) where plan_table_output like ('Plan hash value%');
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hashvalue: 3241900148
Elapsed: 00:00:00.02
LUNAR@lunardb>
LUNAR@lunardb>selectSQL_HANDLE, PLAN_NAME, ENABLED, ACCEPTED, SQL_TEXT
2 from DBA_SQL_PLAN_BASELINES
3 where ACCEPTED = 'YES'
4 order by LAST_MODIFIED;
SQL_HANDLE PLAN_NAME ENA ACC SQL_TEXT
------------------------------ ------------------------------ --- --- --------------------------------------------------------------------------------
SQL_0926b6a1f69f6f5c SQL_PLAN_0k9pqn7v9yvuw02b73393 YES YES select/*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1
Elapsed: 00:00:00.01
LUNAR@lunardb>

下面,我们装载指定的执行计划:

LUNAR@lunardb>variable cnt number ;
LUNAR@lunardb>exec:cnt :=dbms_spm.LOAD_PLANS_FROM_CURSOR_CACHE (SQL_ID => '&SQL_ID',PLAN_HASH_VALUE => &plan_hash_value, SQL_HANDLE => '&SQL_HANDLE') ;
Enter value forsql_id: bjgduva68mbqm
Enter value forplan_hash_value: 1172089107
Enter value forsql_handle: SQL_0926b6a1f69f6f5c
PL/SQLprocedure successfully completed.
Elapsed: 00:00:00.02
LUNAR@lunardb>selectsignature,sql_handle,plan_name,origin,enabled,accepted,autopurge
2 from dba_sql_plan_baselines where CREATED>sysdate-1/48order by created;
SIGNATURE SQL_HANDLE PLAN_NAME ORIGIN ENA ACC AUT
---------------------- ------------------------------ ------------------------------ -------------- --- --- ---
659415202199990108 SQL_0926b6a1f69f6f5c SQL_PLAN_0k9pqn7v9yvuw02b73393 MANUAL-LOAD YES YES YES
Elapsed: 00:00:00.00
LUNAR@lunardb>

确认该执行计划的OUTLINE:

LUNAR@lunardb>SELECT extractValue(value(h),'.') AS hint
2 FROM sys.sqlobj$data od, sys.sqlobj$ so,
3 table(xmlsequence(extract(xmltype(od.comp_data),'/outline_data/hint'))) h
4 WHERE so.name = 'SQL_PLAN_0k9pqn7v9yvuw02b73393'
5 AND so.signature = od.signature
6 AND so.category = od.category
7 AND so.obj_type = od.obj_type
8 AND so.plan_id = od.plan_id;
HINT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
DB_VERSION('11.2.0.4')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1""LUNARTEST1"@"SEL$1"("LUNARTEST1"."N"))
6 rows selected.
Elapsed: 00:00:00.08
LUNAR@lunardb>

这里看到是我们需要的走索引的outline,详细的OUTLINE信息如下:

LUNAR@lunardb>SELECT extractValue(value(h),'.') AS hint
2 FROM sys.sqlobj$data od, sys.sqlobj$ so,
3 table(xmlsequence(extract(xmltype(od.comp_data),'/outline_data/hint'))) h
4 WHERE so.signature = '659415202199990108'
5 AND so.signature = od.signature
6 AND so.category = od.category
7 AND so.obj_type = od.obj_type
8 AND so.plan_id = od.plan_id;
HINT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
DB_VERSION('11.2.0.4')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1""LUNARTEST1"@"SEL$1"("LUNARTEST1"."N"))
END_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
DB_VERSION('11.2.0.4')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1""LUNARTEST1"@"SEL$1"("LUNARTEST1"."N"))
14 rows selected.
Elapsed: 00:00:00.10
LUNAR@lunardb>

现在我们删除profile以前用coe绑定的sql profile:

LUNAR@lunardb>SELECT * FROM DBA_SQL_PROFILES;
NAME CATEGORY SIGNATURE SQL_TEXT
------------------------------ ------------------------------ ---------------------- --------------------------------------------------------------------------------
CREATED LAST_MODIFIED
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
DESCRIPTION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TYPE STATUS FOR TASK_ID TASK_EXEC_NAME TASK_OBJ_ID TASK_FND_ID TASK_REC_ID
------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ----------------
coe_bjgduva68mbqm_3241900148 DEFAULT 659415202199990108 select/*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1
12-JAN-16 11.24.18.000000 AM 12-JAN-16 11.40.52.000000 AM
coe bjgduva68mbqm 3241900148 659415202199990108 9900816299026594015
MANUAL ENABLED NO
Elapsed: 00:00:00.01
LUNAR@lunardb>
LUNAR@lunardb>execdbms_sqltune.drop_sql_profile('coe_bjgduva68mbqm_3241900148');
PL/SQLprocedure successfully completed.
Elapsed: 00:00:00.01
LUNAR@lunardb>SELECT * FROM DBA_SQL_PROFILES;
no rows selected
Elapsed: 00:00:00.00
LUNAR@lunardb>

再次验证SPM的执行计划:

LUNAR@lunardb>select* from table(dbms_xplan.DISPLAY_SQL_PLAN_BASELINE('&sql_handle','&PLAN_NAME'));
Enter value forsql_handle: SQL_0926b6a1f69f6f5c
Enter value forplan_name: SQL_PLAN_0k9pqn7v9yvuw02b73393
old 1: select* from table(dbms_xplan.DISPLAY_SQL_PLAN_BASELINE('&sql_handle','&PLAN_NAME'))
new 1: select* from table(dbms_xplan.DISPLAY_SQL_PLAN_BASELINE('SQL_0926b6a1f69f6f5c','SQL_PLAN_0k9pqn7v9yvuw02b73393'))
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------
SQL handle: SQL_0926b6a1f69f6f5c
SQL text: select/*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1
where n=1
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Plan name: SQL_PLAN_0k9pqn7v9yvuw02b73393 Plan id: 45560723
Enabled: YES Fixed: NO Accepted: YES Origin: MANUAL-LOAD
--------------------------------------------------------------------------------
Plan hashvalue: 3241900148
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 4 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_LUNARTEST1_N | 1 | 4 | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("N"=1)
25 rows selected.
Elapsed: 00:00:00.16
LUNAR@lunardb>

执行SQL,发现SPM可以固定执行计划,使用了我们期待的:

LUNAR@lunardb>setautotrace traceo exp stat
LUNAR@lunardb>select/*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1;
Elapsed: 00:00:00.13
Execution Plan
----------------------------------------------------------
Plan hashvalue: 3241900148
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 4 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_LUNARTEST1_N | 1 | 4 | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("N"=1)
Note
-----
- SQL plan baseline "SQL_PLAN_0k9pqn7v9yvuw02b73393"used forthis statement
Statistics
----------------------------------------------------------
59 recursive calls
52 db block gets
36 consistent gets
1 physical reads
15312 redo size
519 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/fromclient
0 sorts (memory)
0 sorts (disk)
1 rows processed
LUNAR@lunardb>

这里看到已经使用了SPM中的SQL Profile:SQL_PLAN_0k9pqn7v9yvuw02b73393
总结:
这里已经使用了我们的SPM(SQL_PLAN_0k9pqn7v9yvuw02b73393)固定了执行计划,sql使用了索引
说明SPM绑定执行计划的方式比hint的优先级高

免责声明:文章转载自《Oracle 固定执行计划-使用SPM(Sql Plan Management)固定执行计划》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Vue -- 基础深入浅出 Java 虚拟机下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Oracle19c启动监听listener服务

Oracle19c启动监听listener服务 操作系统:win10 Oracle版本:oracle19c 问题描述1 安装了oracle后,win+r输入services.msc发现oracle的服务中没有listener这个监听服务 问题描述2 Unable to OpenSCManager: err=5 TNS-12560: TNS: 协议适配器错误...

B14-iOS开发中的几种存储方式

一、NSUserDefault(偏好设置,Preference) 小规模数据,弱业务相关数据使用。例:某个UISwitch的状态。 二、File(文件存储) 文件存储包括了Plist、archive、Stream等方式,一般结构化的数据或者需要方便查询的数据,都会以Plist的方式去持久化。 Archive方式适合存储平时不太经常使用但很大量的数据,或者读...

ORACLE实例恢复过程详细分析--使用dump、BBED等多种工具结合分析

---友情提示,内容较多,可以从博文左上的+目录选择小节方便阅读。  实验思路:  --实验相关TRACE文件:http://download.csdn.net/detail/q947817003/6646723 1.数据库OPEN,,做DML操作不提交,查看检查点。 2.SHUTDOWN ABORT并重启到MOUNT并查询检查点 3....

mysql复杂查询(一)

所谓复杂查询,指涉及多个表、具有嵌套等复杂结构的查询。这里简要介绍典型的几种复杂查询格式。 一、连接查询 连接是区别关系与非关系系统的最重要的标志。通过连接运算符可以实现多个表查询。连接查询主要包括内连接、外连接等。 假设有Student和Grade两个表如下: +-----+--------+-------+ +-----+-----------...

Oracle函数

Oracle函数 一.字符函数 (1)大小写控制函数 lower():全部小写 select LOWER('SMITH') "CLERK" from DUAL;upper():全部大写 SELECT UPPER('last_name') "Uppercase"FROM dual;initcap():首字母大写 SELECT INITCAP('the soa...

ORACLE 删除重复的数据

内容转自:https://www.cnblogs.com/zfox2017/p/7676237.html 查询及删除重复记录的SQL语句 1、查找表中多余的重复记录,重复记录是根据单个字段(Id)来判断 select Id from 表 group byId having count(Id) > 1 --(查找表中那个字段是重复的) select...