zoukankan      html  css  js  c++  java
  • spm 捕获

    目录

    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);
  • 相关阅读:
    弱网测试—Network-Emulator-Toolkit工具
    chmod修改权限
    mysql:on duplicate key update与replace into
    mysql:批量更新
    linux:磁碟与档案系统管理
    linux:指令与档案的搜索
    linux:问题
    linux:档案与目录管理
    linux:档案权限
    linux:习惯
  • 原文地址:https://www.cnblogs.com/gull/p/8451453.html
Copyright © 2011-2022 走看看