目录

  1. 自动捕获
  2. 从library cache 中加载
  3. 从SQL 调优级加载

1、自动捕获

当optimizer_capture_sql_plan_baselines参数设置为TRUE,查询优化器自动存储新SQL计划的基线,默认是FALSE。

第一个SQL语句被执行只是把signature插入到log日志中,第二次相同的语句执行时,一个SQL执行基线仅包含创建当前执行计划并标记被接受。第三次执行相同的语句时,基线的中执行计划和当前的执行计划做比较,如果不匹配,根据当前的查询优化器做评估,为了保存这些信息,会把当前的执行计划写入sql基线中并标记不接受。

当先的执行计划被存储到SQL执行基线中,以下两种情况很重要做区分

  • 如果他是SQL执行基线中第一个执行计划,执行计划被存储并接受,随后,查询优化器会重用它。
  • 如果SQL语句执行基线中不是第一个执行计划,他会存储不被接受,最后结果,查询优化器不被使用。

2、从library cache 中加载

为了手工加载SQL执行基线加载到数据字典中基于在libarary cache中游标存储,这个dbms_spm包中的load_plans_from_cursor_cache是可用的。

可以把执行计划中本来是全表扫描的,不更改任何的SQL语句,使它走索引的模式。

ALTER SESSION SET optimizer_capture_sql_plan_baselines = TRUE;
SELECT /*+ full(t) */ * FROM employees where employee_id>110; ALTER SESSION SET optimizer_capture_sql_plan_baselines = FALSE;

重新运行语句

SELECT /*+ full(t) */ * FROM employees  where employee_id>110;

查看执行计划

select * from table(dbms_xplan.display_cursor(null,null));
SQL_ID b2j5kmkx67r6t, child number 3
-------------------------------------
SELECT /*+ full(t) */ * FROM employees where employee_id>110 Plan hash value: 603312277 ---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 97 | 6693 | 4 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | EMP_EMP_ID_PK | 97 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("EMPLOYEE_ID">110) Note
-----
- SQL plan baseline
SQL_PLAN_6bu51x6d0cb5215f09a65

通过执行计划中NOTE信息获取sql_handle

 SELECT sql_handle
FROM dba_sql_plan_baselines
WHERE plan_name ='SQL_PLAN_6bu51x6d0cb5215f09a65';

再使语句走INDEX的模式,手工构造HINTS模式

 select /*+index(employees emp_emp_id_pk)*/ * from  employees where employee_id>110;

 select * from table(dbms_xplan.display_cursor(null,null));
SQL_ID 0gd91j77ppkc7, child number 0
-------------------------------------
select /*+index(employees emp_emp_id_pk)*/ * from employees where
employee_id>110 Plan hash value: 603312277 ---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 97 | 6693 | 4 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | EMP_EMP_ID_PK | 97 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("EMPLOYEE_ID">110)

你替换使用在sql基线中的执行计划,加载的执行计划关联索引的,移除全部扫描

declare
ret number(20);
begin
ret := dbms_spm.load_plans_from_cursor_cache(sql_handle => 'SQL_65e8a1e99a062ca2',
sql_id => '0gd91j77ppkc7',
plan_hash_value => '603312277');
end; declare
ret number(20);
begin
ret :=dbms_spm.drop_sql_plan_baseline(sql_handle => 'SQL_65e8a1e99a062ca2',
plan_name => 'SQL_PLAN_6bu51x6d0cb52cf314e9e');
end;

再次执行SQL语句

SELECT /*+ full(t) */ * FROM employees  where employee_id>110; 

select * from table(dbms_xplan.display_cursor(null,null));

SQL_ID  b2j5kmkx67r6t, child number 3
-------------------------------------
SELECT /*+ full(t) */ * FROM employees where employee_id>110 Plan hash value: 603312277 ---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 97 | 6693 | 4 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | EMP_EMP_ID_PK | 97 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("EMPLOYEE_ID">110) Note
-----
- SQL plan baseline
SQL_PLAN_6bu51x6d0cb5215f09a65

全表扫描的SQL语句已经替换为index的模式来处理,为了确认是否使用了SQL基线,你可以核对V$SQL中的SQL_PLAN_BASELINE字段

3、从SQL TUNING SET加载

ret := dbms_spm.load_plans_from_sqlset(sqlset_name => 'test_sqlset',
sqlset_owner => user);

spm 捕获的更多相关文章

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

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

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

    固定执行计划-使用SPM(Sql Plan Management)固定执行计划 转载自:http://www.lunar2013.com/2016/01/固定执行计划-使用spm%EF%BC%88sq ...

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

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

  4. oracle spm使用1

    oracle11g new feature SPM 有助于保持sql的语句特性,仅仅同意运行性能提高的运行计划. 它不同于stored outlines, spm在于稳定sql性能,而store ou ...

  5. Oracle - SPM固定执行计划(一)

    一.前言 生产中偶尔会碰到一些sql,有多种执行计划,其中部分情况是统计信息过旧造成的,重新收集下统计信息就行了.但是有些时候重新收集统计信息也解决不了问题,而开发又在嗷嗷叫,没时间让你去慢慢分析原因 ...

  6. javascript中的事件冒泡和事件捕获

    1.事件冒泡 IE 的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档).以下面的HTML ...

  7. WPF 捕获键盘输入事件

    最近修改的一个需求要求捕获键盘输入的 Text,包括各种标点符号. 最开始想到的是 PreviewKeyDown 或者 PreviewKeyUp 这样的键盘事件. 但是这两个事件的对象 KeyEven ...

  8. .NET 基础 一步步 一幕幕[数组、集合、异常捕获]

    数组.集合.异常捕获 数组: 一次性存储多个相同类型的变量. 一维数组: 语法: 数组类型[] 数组名=new 数组类型[数组长度]; 声明数组的语法: A.数据类型 [] 数组名称= new 数据类 ...

  9. PHP 面向对象编程和设计模式 (4/5) - 异常的定义、扩展及捕获

    PHP高级程序设计 学习笔记 2014.06.12 异常经常被用来处理一些在程序正常执行中遇到的各种类型的错误.比如做数据库链接时,你就要处理数据库连接失败的情况.使用异常可以提高我们程序的容错特性, ...

随机推荐

  1. PySide2运行出错问题解决

    PySide2是QT官方出的Python的QT封装, 不过默认安装运行时候会有一些小问题, 可能是系统里已经安装过其他版本QT的原因, 会报错如下: PySide2 qt.qpa.plugin: Co ...

  2. windows中安装redis的phpredis扩展

    1. 下载php的redis扩展 打开网址 http://pecl.php.net/ (php的扩展库官网),搜索redis,进入地址:http://pecl.php.net/package/redi ...

  3. Hibernate框架学习(八)——查询-HQL语法

    一.单表查询 1.基础语法 2.排序 3.条件 4.分页 5.聚合 6.投影 二.多表查询 1.回顾原生SQL 1>交叉连接-笛卡尔积(避免)select * from A,B; 2>内连 ...

  4. Apache负载均衡配置

    使用mod_proxy 配置Apache负载均衡 1.安装apache ./configure --prefix=/usr/local/apache2 –enable-so make &&am ...

  5. 从Dinnr失败看产品市场可行性认知有哪些不足

    对所有互联网创始人来说,在实际创业之前「验证idea的市场可行性」是至关重要的事情,许多人会用访谈的方式询问潜在顾客的意见,本期的就已Dinnr为案例,当初用户访谈结果乐观,实际上线后却无人买单,创办 ...

  6. testng+selnium+eclipse的测试框架运用

    一:TestNG在Eclipse中的安装(1)点击eclipse中的Help->Install New Software (2)点击[Add]按钮,输入相应的地址(3)勾选加载出来的TestNG ...

  7. 小程序(Wepy)--生成海报图片

    对于小程序的分享, 除了分享给朋友, 好友群,是可以直接做到的, 但是要想扩大推广范围, 通过生成海报图片, 将自己小程序码带进去,应该是目前我所知的好办法了. 但是海报也不是那么好搞.之前自己手写出 ...

  8. ios兼容 input输入时弹出键盘框 页面整体上移键盘框消失后在ios上页面不能回弹的问题

    前端h5混合开发手机端ios  当有input输入时,手机下方弹出键盘使页面上移,当输入完成,键盘消失后页面显示回到原位,但实际不能点击(可点击上方区域,有反应),也就是说实际是没有回弹. 解决办法: ...

  9. Codeforces 667B Coat of Anticubism

    链接:传送门 题意:题目balabala说了一大堆,然而并没什么卵用,给你n个数,将这个集合分割成两部分,构成三角形的两个边,让你求补充的那个边最短是多长 思路:三角形三边具有 a + b > ...

  10. 原生JS封装ajax以及request

    一.封装原生的xhr为ajax类 xhr以及用法见之前的文章 1.根据url确定请求的头部以及别的信息. var _headerConfig = {}; if(url.indexOf('getcapt ...