固定执行计划-使用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>select signature,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 for sql_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/SQL procedure successfully completed.
 
Elapsed: 00:00:00.21
LUNAR@lunardb>
LUNAR@lunardb>select signature,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 hash value: 3241900148
 
Elapsed: 00:00:00.02
LUNAR@lunardb>
LUNAR@lunardb>select SQL_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 for sql_id: bjgduva68mbqm
Enter value for plan_hash_value: 1172089107
Enter value for sql_handle: SQL_0926b6a1f69f6f5c
 
PL/SQL procedure successfully completed.
 
Elapsed: 00:00:00.02
LUNAR@lunardb>select signature,sql_handle,plan_name,origin,enabled,accepted,autopurge
  2  from dba_sql_plan_baselines where CREATED>sysdate-1/48 order 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>exec dbms_sqltune.drop_sql_profile('coe_bjgduva68mbqm_3241900148');
 
PL/SQL procedure 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 for sql_handle: SQL_0926b6a1f69f6f5c
Enter value for plan_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 hash value: 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>set autotrace 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 hash value: 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 for this 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/from client
          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)固定执行计划的更多相关文章

  1. 11g新特性-SQL Plan Management

    在11g之前版本,提供了stored outlines(sql概要)特性来保存sql的执行计划. 在11g中,引入了一个新的特性sql计划管理(sql plan management)特性来保存sql ...

  2. oracle11g中SQL优化(SQL TUNING)新特性之SQL Plan Management(SPM)

    1.   简介 Oracle Database11gR1引进了SQL PlanManagement(简称SPM),一套允许DBA捕获和保持任意SQL语句执行计划最优的新工具,这样,限制了刷新优化器统计 ...

  3. 11g的新特性:SQL Plan Management(SPM)

    Oracle11g中,Oracle提供dbms_spm包来管理SQL Plan,SPM是一个预防机制,它记录并评估sql的执行计划,将已知的高效的sql执行计划建立为SQL Plan Baseline ...

  4. Bullet:ORACLE Using SQL Plan Management(一)

    SQL Plan Management如何工作? 当一个SQL硬解析时,基于成本的优化器CBO会生成多个执行计划,并从这些执行计划中选择一个优化器认为最低成本的执行计划. 如果SQL plan bas ...

  5. Oracle 11g 新特性 --SQL Plan Management 说明

    Oracle 11g 新特性 --SQL Plan Management 说明 参见大神博主文章: http://blog.csdn.net/tianlesoftware/article/detail ...

  6. SQL Server Management Studio 执行超大脚本文件

    SQL Server Management Studio 执行超大脚本文件 启动cmd.exe , cd 到C:\Program Files (x86)\Microsoft SQL Server\11 ...

  7. 存储过程被程序和第三方客户端执行很慢,而sql server management studio执行速度正常

    来自:http://blog.csdn.net/pgbiao/article/details/22388945 原因分析:由于存储过程是预编译的, 在第一次执行的时候, 会生成执行计划, 以后执行的时 ...

  8. 官方文档:11G新特性SQL PLAN BASLINE 执行计划基线

    什么是SQL执行计划管理? SQL计划管理(SQL plan management)是一咱预防机制,记录和评估SQL语句的执行计划.SQL plan management的主要功能是sql plan ...

  9. SQL Server-聚焦sp_executesql执行动态SQL查询性能真的比exec好?

    前言 之前我们已经讨论过动态SQL查询呢?这里为何再来探讨一番呢?因为其中还是存在一定问题,如标题所言,很多面试题也好或者有些博客也好都在说在执行动态SQL查询时sp_executesql的性能比ex ...

随机推荐

  1. ubuntu启动google_chrome报错:FATAL:nss_util.cc(632)] NSS_VersionCheck("3.26") failed. NSS >= 3.26 is required. Please upgrade to the latest NSS

    一.背景: jello@jello:~$ lsb_release -aNo LSB modules are available.Distributor ID:    Ubuntu KylinDescr ...

  2. 分布式系统一致性算法Raft

    Raft 算法也是一种少数服从多数的算法,在任何时候一个服务器可以扮演以下角色之一:Leader:负责 Client 交互 和 log 复制,同一时刻系统中最多存在一个Follower:被动响应请求 ...

  3. 不在同一主机:vsftpd+pam+mysql

    配置环境:Centos7上的mariadb + Centos6上的vsftpd 一.安装所需要程序 1.安装vsftpd和pam_mysql(在centos6-->192.168.108.160 ...

  4. UVa 1631 密码锁

    https://vjudge.net/problem/UVA-1631 题意: 有一个n位密码锁,每位都是0~9,可以循环旋转.每次可以让1~3个相邻数字同时往上或者往下转一格.输入初始状态和终止状态 ...

  5. php五大运行模式CGI,FAST-CGI,CLI,ISAPI,APACHE模式

    做 php 开发的应该都知道 php 运行模式概念吧,本文将要和大家分享的是关于php目前比较常见的五大运行模式:包括cgi .fast-cgi.cli.isapi.apache模块的DLL ,下面作 ...

  6. Git operate

    新建远程分支和删除 https://www.jianshu.com/p/ea1dab2de419 使用git branch -a查看所有分支 远程先开好分支然后拉到本地 git checkout -b ...

  7. hdu 2824 The Euler function 欧拉函数打表

    The Euler function Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  8. Jmeter 4.0 扩展插件

    今天发现Jmeter4.0 也可以安装插件 而且比之前的版本的安装方法更为容易 https://jmeter-plugins.org/ https://jmeter-plugins.org/insta ...

  9. HTML元素1: 基本元素,标题,段落,链接,图像等

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. Django内置模版过滤器

    Django内置过滤器总览 可以查询下表来总览Django的内置过滤器: 过滤器 说明 add 加法 addslashes 添加斜杠 capfirst 首字母大写 center 文本居中 cut 切除 ...