• SQL baseline_11g


    conn sh/sh
    --执行想要创建基线的语句,语句的执行计划将会被缓存
    set autotrace on
    select /*ghbaselines1*/ count(*) from customers join countries using ( country_id )
    where country_name = 'New Zealand' and cust_income_level = 'G: 130,000 - 149,999'
    and cust_year_of_birth < '1952' ;

    --从游标缓存区中手动载入关于这个SQL的执行计划做为基线
    conn / as sysdba

    declare
    v_sql_id v$sql.sql_id%type ;
    v_plan_count number ;
    begin
    select sql_id into v_sql_id from v$sql
    where sql_text like 'select /*ghbaselines1*/%' ;
    v_plan_count := dbms_spm.load_plans_from_cursor_cache( sql_id => v_sql_id ) ;
    dbms_output.put_line( v_plan_count || ' plans loaded' ) ;
    end ;
    /

    --查看基线的信息,这个基线的状态是ACCEPTED,是将会被优化器使用的
    select sql_handle , plan_name , origin , accepted , optimizer_cost as cost from dba_sql_plan_baselines
    where sql_text like 'select /*ghbaselines1*/%' ;

    SQL_HANDLE PLAN_NAME ORIGIN ACC COST
    ------------------------------ ------------------------------ -------------- --- ----------
    SYS_SQL_a8f88a44571be8dd SQL_PLAN_ajy4a8jbjru6x0e60872e MANUAL-LOAD YES 409

    --查看基线里面的执行计划
    var v_sql_handle varchar2(50) ;
    exec :v_sql_handle := 'SYS_SQL_a8f88a44571be8dd' ;

    PL/SQL procedure successfully completed.

    select * from table(dbms_xplan.display_sql_plan_baseline(:v_sql_handle , null , 'basic' ) ) ;

    --创建索引
    conn sh/sh
    create index cust_country_index_dob_ix on customers( country_id , cust_income_level , cust_year_of_birth ) ;

    --查看执行计划是否有变化,因为基线的存在执行计划并没有变化,执行计划获得了稳定
    set autotrace on
    select /*ghbaselines1*/ count(*) from customers join countries using ( country_id )
    where country_name = 'New Zealand' and cust_income_level = 'G: 130,000 - 149,999'
    and cust_year_of_birth < '1952' ;

    --查看新的基线(新的执行计划由优化器生成,但是由于基线的存在并没有被使用,即使更好,但是会生成一个新的基线)
    --两个基线的SQL_HANDLE是一样的。
    conn / as sysdba

    select sql_handle , plan_name , origin , accepted , optimizer_cost as cost
    from dba_sql_plan_baselines
    where sql_text like 'select /*ghbaselines1*/%' ;

    SQL_HANDLE PLAN_NAME ORIGIN ACC COST
    ------------------------------ ------------------------------ -------------- --- ----------
    SYS_SQL_a8f88a44571be8dd SQL_PLAN_ajy4a8jbjru6x0e60872e MANUAL-LOAD YES 409
    SYS_SQL_a8f88a44571be8dd SQL_PLAN_ajy4a8jbjru6x5b4b1285 AUTO-CAPTURE NO 5

    --进化基线,verify为YES表示对性能有提升才会被接受。Commit表示直接接受,而不是给出建议。
    var v_sql_handle varchar2(50)
    exec :v_sql_handle := 'SYS_SQL_a8f88a44571be8dd'
    var v_report varchar2(2000)
    begin
    :v_report := dbms_spm.evolve_sql_plan_baseline ( sql_handle => :v_sql_handle ,
    verify => 'YES' ,
    commit => 'YES' ) ;
    end ;
    /

    --查看报告
    set serveroutput on
    exec dbms_output.put_line(:v_report ) ;

    --查看进化后的基线是否生效,结果表明执行计划在稳定的基础上获得了提升
    conn sh/sh

    set autotrace on

    select /*ghbaselines1*/ count(*) from customers join countries using ( country_id )
    where country_name = 'New Zealand' and cust_income_level = 'G: 130,000 - 149,999'
    and cust_year_of_birth < '1952' ;

    --查看新的基线信息,两个都是接受的,但是Oracle当然会选Cost小的
    select sql_handle , plan_name , origin , accepted , optimizer_cost as cost
    from dba_sql_plan_baselines where sql_text like 'select /*ghbaselines1*/%' ;

    SQL_HANDLE PLAN_NAME ORIGIN ACC COST
    ------------------------------ ------------------------------ -------------- --- ----------
    SYS_SQL_a8f88a44571be8dd SQL_PLAN_ajy4a8jbjru6x0e60872e MANUAL-LOAD YES 409
    SYS_SQL_a8f88a44571be8dd SQL_PLAN_ajy4a8jbjru6x5b4b1285 AUTO-CAPTURE YES 5

    --查看基线的执行计划,两个都会被展示
    select * from table(dbms_xplan.display_sql_plan_baseline('SYS_SQL_a8f88a44571be8dd' , null , 'basic' ) ) ;


    -----------------------------------------------------------------------------------------------------------------------------------------------
    Oracle SQL执行计划基线总结(SQL Plan Baseline)
    一、基础概念
    Oracle 11g开始,提供了一种新的固定执行计划的方法,即SQL plan baseline,中文名SQL执行计划基线(简称基线),可以认为是OUTLINE(大纲)或者SQL PROFILE的改进版本,基本上它的主要作用可以归纳为如下两个:
    1、稳定给定SQL语句的执行计划,防止执行环境或对象统计信息等等因子的改变对SQL语句的执行计划产生影响!
    2、减少数据库中出现SQL语句性能退化的概率,理论上不允许一条语句切换到一个比已经执行过的执行计划慢很多的新的执行计划上!
    注意:
    1、从Oracle的发展角度来看,估计这种方法是Oracle发展和改进的方向,如今outline已经被废弃,sql profile估计在后续的发行版本中也难有改进,因此,对于从11g开始接触Oracle的朋友来说,一定要对sql计划基线有所了解,因为这是以后的主流!
    2、SQL执行计划基线保存在数据字典中,查询优化器会自动判断使用他们。

    Oracle教程:实例故障恢复 http://www.linuxidc.com/Linux/2011-08/40857.htm
    Linux-6-64下安装Oracle 12C笔记 http://www.linuxidc.com/Linux/2013-07/86805.htm
    在CentOS 6.4下安装Oracle 11gR2(x64) http://www.linuxidc.com/Linux/2014-02/97374.htm
    Oracle 11gR2 在VMWare虚拟机中安装步骤 http://www.linuxidc.com/Linux/2013-09/89579p2.htm
    Debian 下 安装 Oracle 11g XE R2 http://www.linuxidc.com/Linux/2014-03/98881.htm

    二、工作机制
    从Oracle 11g开始,由于基线的存在,一条语句的解析过程大概如下:
    1.SQL语句被硬解析后,CBO(优化器)会产生很多个的执行计划,CBO从中选择一个成本最低执行计划。
    2.基于SQL语句的文本形成一个哈希值(signature),通过这个哈希值来检查数据字典中是否存在同样的基线。
    3.如果基线存在,优化器会对刚刚产生的执行计划和保存在SQL plan baseline中的执行计划进行比较。
    4.如果基线中有与CBO刚产生的执行计划的匹配的SQL执行计划存在,并且被标记为可接受(‘accepted’),则这个CBO生成的执行计划被启用。
    5.如果基线中没有匹配的SQ执行计划存在,CBO评估基线中被标记为‘accepted’的的多个执行计划,并选择其中cost最低的执行计划。(注意,一个语句的基线可以有多个执行计划被保存,这是与其他Outline和SQL profiel都不同的地方)
    6.如果刚刚硬解析过程中CBO选择的执行计划比保存在基线中的执行计划COST都低,这个新生成的执行计划被标记为‘not-accepted’并保存在基线中。直到这个执行计划被演化且验证后才会被考虑使用,即标记为accepted(演化和验证,可以简单理解为Oracle确认这个执行计划可以带来更好的性能)。
    Oracle 就是通过上面这种方式来确保SQL语句的性能不会退化(即第一部分中我归纳的第二个主要作用),称为“执行计划保守选择策略”

    三、基线的一些特点
    1.通过OPTIMIZER_USE_SQL_PLAN_BASELINE来控制Oracle是否使用基线,默认值为TRUE,即会自动使用基线。
    2.11g中默认是不会自动创建基线
    3.与OUTLINE和SQL Profile不同,基线中不存在分类的概念
    4.与OUTLINE和SQL Profile不同,每个SQL语句可以有多个基线。Oracle根据制定的规则来判断具体是否哪个基线
    5.基线针对RAC中所有的实例都生效
    6.基线有两个表示,一个为sql_handle,可以理解为表示语句文本的唯一标识,一个为sql_plan_name可以理解为执行计划的唯一标识
    7.不能像sql profile一样通过force_matching属性将字面值不一样的SQL语句使用一个基线应用多个语句。

    三、创建基线的几种方式
    1、自动捕获基线,通过将optimizer_cature_sql_plan_baselines设置为true,优化器为重复执行两次以上的SQL语句生成并保存基线(可以系统级或会话级修改)
    2、从SQL调优集合中加载,通过使用包dbms_spm.load_plans_from_sqlset来从SQL调优集合中加载基线

    DECLARE
    l_plans_loaded PLS_INTEGER;
    BEGIN
    l_plans_loaded := DBMS_SPM.load_plans_from_sqlset(
    sqlset_name => 'my_sqlset');
    END;
    /

    3、从库缓存中加载,通过包dbms_spm.load_plans_from_cursor_cache函数为一条已经在游标缓存中的语句创建基线

    DECLARE
    l_plans_loaded PLS_INTEGER;
    BEGIN
    l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(sql_id => '1fkh93md0802n',plan_hash_value=>null);
    END;
    /

    --备注:可以有多种方式加载,例如可以根据sql文本进行模糊匹配、SQL语句解析的用户名等等方式,具体见文档

    四、基线的几种状态
    一个SQL语句对应的基线,我将它们归纳为三种状态
    1.accepted(可接受),只有这种状态的基线,优化器才会考虑此基线中的执行计划
    2.no-accepted(不可接受),这种状态的基线,优化器在SQL语句解析期间不会考虑。这种状态的基线必须通过演化和验证通过后,转变为accepted状态后,才会被优化器考虑使用
    3.fixed为yes(固定),这种状态的基线固有最高优先级!比其他两类基线都要优先考虑

    五、查看基线
    --1、基本视图:dba_sql_plan_baselines、dba_sql_management_config
    --*******************************************************************************************************************************
    --2、底层视图:sqlobj$data 、 sqlobj$ (保存具体的hint),如下查看基线中保存的执行计划语句:
    select
    extractvalue(value(d), '/hint') as outline_hints from
    xmltable('/outline_data/hint'
    passing (
    select
    xmltype(comp_data) as xmlval
    from
    sqlobj$data sod, sqlobj$ so
    where so.signature = sod.signature
    and so.plan_id = sod.plan_id
    and comp_data is not null
    and name like '&baseline_plan_name'
    )
    ) d;

    --3、通过函数来查看基线的详细信息:
    select * from table(dbms_xplan.display_sql_plan_baseline(sql_handle=>'SYS_SQL_11bcd50cd51504e9',plan_name=>'SQL_PLAN_13g6p1maja1790cce5f0e'));

    六、演化基线
    为了验证基线中一个处于不可接受状态的执行计划是否比一个处于可接受状态的执行计划具有更高的效率,必须通过演化来验证,需要让优化器以不同的执行计划来执行这条SQL语句,观察不可接受状态的执行计划基线是否会带来更好的性能,如果性能确实更高,这个不可接受状态的基线将会转换为可接受状态。演化的方式有两种:

    1、手工执行运行
    SELECT DBMS_SPM.evolve_sql_plan_baseline(sql_handle => 'SYS_SQL_xxxxxxxxxxxxx') From dual;

    还有time_limit/verify/commit几个参数,可以参考文档

    2、调优包实现基线的自动演化,可以理解为,启动一个调度任务,周期性的检查是否有不可接受状态的基线可以被演化

    七、修改基线

    可以通过dbms_spm.alter_sql_plan_baseline包来修改基线的一些属性,主要有如下几个属性

    1.ENABLED :设置该属性的值为NO告诉Oracle 11g临时禁用某个计划,一个SQL计划必须同时标记为ENABLED和ACCEPTED,否则CBO将忽略它
    2.FIXED:设置为YES,那个计划将是优化器唯一的选择[最高优先级],即使如果某个计划可能拥有更低的成本。这让DBA可以撤销SMB的默认行为,对于转换一个存储概要进入一稳定的SQL计划基线特别有用,注意当一个新计划被添加到被标记为FIXED的SQL计划基线,该新计划不能被利用除非它申明为FIXED状态
    3.AUTOPURG:设置这个属性的值为NO告诉Oracle 11g无限期保留它,从而不用担心SMB的自动清除机制
    4.plan_name : 改变SQL plan 名字
    5.description : 改变SQL plan描述

    SET SERVEROUTPUT ON

    DECLARE
    v_text PLS_INTEGER;
    BEGIN
    v_text := DBMS_SPM.alter_sql_plan_baseline(sql_handle => 'SYS_SQL_xxxxxx',plan_name => 'SYS_SQL_PLAN_xxxxxxxxx',
    attribute_name => 'fixed',attribute_value => 'YES');
    DBMS_OUTPUT.put_line('Plans Altered: ' || v_text );
    END;
    /

    八、迁移基线
    dbms_spm提供了多个过程来在数据库之间迁移SQL计划基线
    create_stgtab_baseline创建一个计划基线保存表
    pack_stgtab_baseline将基线从数据字典复制到第一步的表中
    unpack_stgtab_baseline将基线从保存表中复制到迁移数据库的数据字典中
    大概过程如下:
    1、创建一张保存数据字典中基线表内容的用户表
    exec dbms_spm.create_stgtab_baseline(table_name => 'BASELINE_TEST',table_owner => 'SCOTT',tablespace_name =>'');
    2、将数据字典中基线表的内容 插入到 第一步创建的用户表中
    exec :i := dbms_spm.pack_stgtab_baseline(table_name => 'BASELINE_TEST', table_owner => 'SCOTT');
    备注:可以支持多种方式插入,例如包含特定字符的SQL相关的基线,sql_handle来精确识别一个基线,具体见文档
    3、通过迁移工具迁移用户表
    exp/imp or expdp/impdp
    4、将迁移过来的用户表中保存的基线内容 插入到当前库的数据字典中,从而实现迁移
    exec :i := dbms_spm.unpack_stgtab_baseline(table_name => 'BASELINE_TEST',table_owner => 'SCOTT');
    备注:可以支持多种方式,与步骤2一样,具体见文档

    九、删除基线
    可以通过dbms_SPM.drop_sql_plan_baseline包来手工删除数据字典里的基线
    为使用的基线,fixed为no的基线,将在一定的保留期后自动删除(可查看dba_sql_management_config视图)
    手工删除方法如下
    SET SERVEROUTPUT ON
    DECLARE
    v_text PLS_INTEGER;
    BEGIN
    v_text := DBMS_SPM.drop_sql_plan_baseline(sql_handle => 'SYS_SQL_7b76323ad90440b9',plan_name => NULL);
    DBMS_OUTPUT.put_line(v_text);
    END;
    /

    十、将一个SQL语句固定为我们期望的执行计划
    我一般通过如下几步实现(仅供参考)
    1、为这个SQL语句创建基线
    2、给这个SQL语句添加hint赖宇星,确保SQL语句添加hint后的执行计划与我们期望一样
    3、将第2步产生的执行计划,添加到第一步创建的基线中(注意,前面已经说过,一个SQL语句可以有多个基线!)
    4、删除基线中第1步创建的那个执行计划(这样,我们就可以确保基线中只有我们期望的执行计划,即保存第2步SQL语句的执行计划)
    5、验证是否生效
    后续有示例,加深理解!

    十一、示例(将一个SQL语句固定为我们期望的执行计划)
    首先运行两个结构相同的语句,下面的实验通过SQL计划基线,将一个语句的执行计划通过另一个语句的执行计划来固定
    SQL> select sql_handle,plan_name,dbms_lob.substr(sql_text,60,1) sql_text,ACCEPTED from dba_sql_plan_baselines;
    未选定行
    SQL> alter system flush shared_pool;
    系统已更改。
    SQL> select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where id=711;
    ID NAME TYPE
    ---------- ------------------------------ ---------------
    711 I_STREAMS_PROCESS_PARAMS1 INDEX
    SQL> select /* outlinetest3 */ /*+ index(dh_stat) */ * from dh_stat where id=711;
    ID NAME TYPE
    ---------- ------------------------------ ---------------
    711 I_STREAMS_PROCESS_PARAMS1 INDEX

    SQL> select sql_text,sql_id,hash_value,child_number,plan_hash_value,to_char(LAST_ACTIVE_TIME,'hh24:mi:ss') time
    2 from v$sql a where sql_text like '%outlinetest%' and sql_text not like '%v$sql%';
    SQL_TEXT SQL_ID HASH_VALUE CHILD_NUMBER PLAN_HASH_VALUE TIME
    ------------------------------------------------------- ------------- ---------- ------------ --------------- --------
    select /* outlinetest2 */ /*+ full(dh_stat) */ * from d 4vaj9fgjysy9c 3823925548 0 1845196118 12:27:31
    h_stat where id=711
    select /* outlinetest3 */ /*+ index(dh_stat) */ * from fm35jcmypb3qu 4250242778 0 2780970545 12:27:41
    dh_stat where id=711

    SQL> select * from table(dbms_xplan.display_cursor('4vaj9fgjysy9c','',''));
    PLAN_TABLE_OUTPUT
    ---------------------------------------------------------------------------------------------------------------------------------
    SQL_ID 4vaj9fgjysy9c, child number 0
    -------------------------------------
    select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where
    id=711
    Plan hash value: 1845196118
    -----------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    -----------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | | | 124 (100)| |
    |* 1 | TABLE ACCESS FULL| DH_STAT | 1 | 38 | 124 (1)| 00:00:02 |
    -----------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    1 - filter("ID"=711)
    已选择19行。

    SQL> select * from table(dbms_xplan.display_cursor('fm35jcmypb3qu','',''));
    PLAN_TABLE_OUTPUT
    ---------------------------------------------------------------------------------------------------------------------------------
    SQL_ID fm35jcmypb3qu, child number 0
    -------------------------------------
    select /* outlinetest3 */ /*+ index(dh_stat) */ * from dh_stat where
    id=711
    Plan hash value: 2780970545
    ---------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    ---------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | | | 2 (100)| |
    | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    2 - access("ID"=711)
    已选择20行。


    SQL> DECLARE
    2 k1 pls_integer;
    3 begin
    4 k1 := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
    5 sql_id=>'4vaj9fgjysy9c',
    6 plan_hash_value=>1845196118
    7 );
    8 end;
    9 /
    PL/SQL 过程已成功完成。

    SQL> select sql_handle,plan_name,dbms_lob.substr(sql_text,60,1) sql_text,ACCEPTED from dba_sql_plan_baselines;

    SQL_HANDLE PLAN_NAME SQL_TEXT ACC
    ------------------------------ ------------------------------ ------------------------------------------------------- ---
    SYS_SQL_11bcd50cd51504e9 SQL_PLAN_13g6p1maja17934f41c8d select /* outlinetest2 */ /*+ full(dh_stat) */ * from d YES
    h_sta

    刚生产sql plan baseline的时候,第一次查询,无法找到执行计划,直到第二次执行的时候,才能看到,如下
    SQL> select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where id=711;
    ID NAME TYPE
    ---------- ------------------------------ ---------------
    711 I_STREAMS_PROCESS_PARAMS1 INDEX
    SQL> select * from table(dbms_xplan.display_cursor('4vaj9fgjysy9c','',''));
    PLAN_TABLE_OUTPUT
    ---------------------------------------------------------
    SQL_ID: 4vaj9fgjysy9c cannot be found
    SQL> select sql_text,sql_id,hash_value,child_number,plan_hash_value,to_char(LAST_ACTIVE_TIME,'hh24:mi:ss') time
    2 from v$sql a where sql_text like '%outlinetest%' and sql_text not like '%v$sql%';
    SQL_TEXT SQL_ID HASH_VALUE CHILD_NUMBER PLAN_HASH_VALUE TIME
    ------------------------------------------------------- ------------- ---------- ------------ --------------- --------
    select /* outlinetest3 */ /*+ index(dh_stat) */ * from fm35jcmypb3qu 4250242778 0 2780970545 12:27:41
    dh_stat where id=711

    SQL> select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where id=711;
    ID NAME TYPE
    ---------- ------------------------------ ---------------
    711 I_STREAMS_PROCESS_PARAMS1 INDEX
    SQL> select sql_text,sql_id,hash_value,child_number,plan_hash_value,to_char(LAST_ACTIVE_TIME,'hh24:mi:ss') time
    2 from v$sql a where sql_text like '%outlinetest%' and sql_text not like '%v$sql%';

    SQL_TEXT SQL_ID HASH_VALUE CHILD_NUMBER PLAN_HASH_VALUE TIME
    ------------------------------------------------------- ------------- ---------- ------------ --------------- --------
    select /* outlinetest2 */ /*+ full(dh_stat) */ * from d 4vaj9fgjysy9c 3823925548 0 1845196118 12:30:54
    h_stat where id=711
    select /* outlinetest3 */ /*+ index(dh_stat) */ * from fm35jcmypb3qu 4250242778 0 2780970545 12:27:41
    dh_stat where id=711

    SQL> select * from table(dbms_xplan.display_cursor('4vaj9fgjysy9c','',''));
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------
    SQL_ID 4vaj9fgjysy9c, child number 0
    -------------------------------------
    select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where
    id=711

    Plan hash value: 1845196118
    -----------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    -----------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | | | 124 (100)| |
    |* 1 | TABLE ACCESS FULL| DH_STAT | 1 | 38 | 124 (1)| 00:00:02 |
    -----------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------

    1 - filter("ID"=711)
    Note
    -----
    - SQL plan baseline SQL_PLAN_13g6p1maja17934f41c8d used for this statement
    已选择23行。

    将符合我们预期的执行计划的加载到第一次生成的sql baseline中!
    SQL> DECLARE
    2 k1 pls_integer;
    3 begin
    4 k1 := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
    5 sql_id=>'fm35jcmypb3qu',
    6 plan_hash_value=>2780970545,sql_handle=>'SYS_SQL_11bcd50cd51504e9'
    7 );
    8 end;
    9 /

    PL/SQL 过程已成功完成。

    可以看到,SYS_SQL_11bcd50cd51504e9下目前有两个plan_name
    SQL> select sql_handle,plan_name,dbms_lob.substr(sql_text,60,1) sql_text,ACCEPTED from dba_sql_plan_baselines;

    SQL_HANDLE PLAN_NAME SQL_TEXT ACC
    ------------------------------ ------------------------------ ------------------------------------------------------- ---
    SYS_SQL_11bcd50cd51504e9 SQL_PLAN_13g6p1maja1790cce5f0e select /* outlinetest2 */ /*+ full(dh_stat) */ * from d YES
    h_sta

    SYS_SQL_11bcd50cd51504e9 SQL_PLAN_13g6p1maja17934f41c8d select /* outlinetest2 */ /*+ full(dh_stat) */ * from d YES
    h_sta
    删除第一个plan_name,即将我们不需要的执行计划版本去除掉!
    SQL> DECLARE
    2 k1 pls_integer;
    3 begin
    4 k1 := DBMS_SPM.drop_sql_plan_baseline ( sql_handle=>'SYS_SQL_11bcd50cd51504e9',plan_name=>'SQL_PLAN_13g6p1maja17934f41c8d');
    5 end;
    6 /

    PL/SQL 过程已成功完成。

    通过下面的一部分测试,我们可以看到,新的SQL计划基线已经正常生效,及时语句中包含full提示,执行计划也走索引定位数据
    SQL> select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where id=711;
    ID NAME TYPE
    ---------- ------------------------------ ---------------
    711 I_STREAMS_PROCESS_PARAMS1 INDEX

    SQL> select * from table(dbms_xplan.display_cursor('4vaj9fgjysy9c','',''));
    PLAN_TABLE_OUTPUT
    -----------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID 4vaj9fgjysy9c, child number 1
    -------------------------------------
    select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where
    id=711
    Plan hash value: 2780970545
    ---------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    ---------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | | | 2 (100)| |
    | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    2 - access("ID"=711)
    Note
    -----
    - SQL plan baseline SQL_PLAN_13g6p1maja1790cce5f0e used for this statement
    已选择24行。


    可以通过dba_sql_plan_baselines来显示可用的SQL计划基线的一般信息,也可以通过如下这种方式显示执行SQL计划基线的详细信息!
    select * from table(dbms_xplan.display_sql_plan_baseline(sql_handle=>'SYS_SQL_11bcd50cd51504e9',plan_name=>'SQL_PLAN_13g6p1maja1790cce5f0e'));

    PLAN_TABLE_OUTPUT
    -----------------------------------------------------------------------------------------------------------------------------------------------
    SQL handle: SYS_SQL_11bcd50cd51504e9
    SQL text: select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where
    id=711
    --------------------------------------------------------------------------------

    --------------------------------------------------------------------------------
    Plan name: SQL_PLAN_13g6p1maja1790cce5f0e Plan id: 214851342
    Enabled: YES Fixed: NO Accepted: YES Origin: MANUAL-LOAD
    --------------------------------------------------------------------------------

    Plan hash value: 2780970545

    ---------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    ---------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 38 | 2 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------

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

    2 - access("ID"=711)
    已选择26行。

    查看SQL计划基线中保存的hint提示集合
    SQL> conn /as sysdba
    已连接。
    SQL> select
    2 extractvalue(value(d), '/hint') as outline_hints
    3 from
    4 xmltable('/outline_data/hint'
    5 passing (
    6 select
    7 xmltype(comp_data) as xmlval
    8 from
    9 sqlobj$data sod, sqlobj$ so
    10 where so.signature = sod.signature
    11 and so.plan_id = sod.plan_id
    12 and comp_data is not null
    13 and name like '&baseline_plan_name'
    14 )
    15 ) d;
    输入 baseline_plan_name 的值: SQL_PLAN_13g6p1maja1790cce5f0e
    原值 13: and name like '&baseline_plan_name'
    新值 13: and name like 'SQL_PLAN_13g6p1maja1790cce5f0e'

    OUTLINE_HINTS
    --------------------------------------------------------------------------------------------------------------------------
    IGNORE_OPTIM_EMBEDDED_HINTS
    OPTIMIZER_FEATURES_ENABLE('11.2.0.1')
    DB_VERSION('11.2.0.1')
    ALL_ROWS
    OUTLINE_LEAF(@"SEL$1")
    INDEX_RS_ASC(@"SEL$1" "DH_STAT"@"SEL$1" ("DH_STAT"."ID"))

    已选择6行。
    更多Oracle相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12
    本文永久更新链接地址:http://www.linuxidc.com/Linux/2014-07/103935.htm

  • 相关阅读:
    u3d Mecanim动画
    四元数的共轭和逆
    c++ 单例模式
    GVIM、VIM
    Linux磁盘管理——虚拟文件系统
    Linux磁盘管理——MBR 与 GPT
    Link monitoring
    Linux高级网络设置——将多个网卡设置成一个网卡
    Linux高级网络设置——给网卡绑定多个IP
    DNS原理极限剖析
  • 原文地址:https://www.cnblogs.com/buffercache/p/10715732.html
Copyright © 2020-2023  润新知