• coe_load_sql_profile脚本绑定执行计划


    可以使用coe_load_sql_profile.sql脚本直接固定执行计划,该脚本也可以实现直接把sqlprofile直接迁移到其它库中。

    SQLT工具包含一个脚本,SQLT可以在Doc ID 215187.1中下载。

    很多DBA习惯于使用coe_xfr_sql_profile.sql脚本来固定SQL执行计划,但是这个脚本操作起来比较麻烦,而且容易出错。这个脚本的正确用途是用来做不同数据库之间SQL执行计划的固定。最方便的脚本是:coe_load_sql_profile.sql,使用这个脚本,只需要输入几个参数,就能完成快速恢复执行计划的任务。

    需要注意的是,该脚本不能以SYS用户执行,否则会报如下的错误:

    DECLARE

    *

    ERROR at line 1:

    ORA-19381: cannot create staging table in SYS schema

    ORA-06512: at "SYS.DBMS_SMB", line 313

    ORA-06512: at "SYS.DBMS_SQLTUNE", line 6306

    ORA-06512: at line 64

    示例如下:

    1.1.  建立测试表和数据

    SYS@dlhr> select * from v$version;
     BANNER
    --------------------------------------------------------------------------------
    Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
    PL/SQL Release 11.2.0.4.0 - Production
    CORE    11.2.0.4.0      Production
    TNS for IBM/AIX RISC System/6000: Version 11.2.0.4.0 - Production
    NLSRTL Version 11.2.0.4.0 - Production
     
    LHR@dlhr> create table scott.test as select * from dba_objects;
     Table created.
     LHR@dlhr> create index scott.idx_test_01 on scott.test(object_id);
     Index created.
     ---收集统计信息
    LHR@dlhr> exec dbms_stats.gather_table_stats('scott','test',cascade=>true);
     PL/SQL procedure successfully completed.
     
    LHR@dlhr> update scott.test set object_id=10 where object_id>10;
     
    LHR@dlhr> commit;
    Commit complete.
    
    LHR@dlhr> select OBJECT_ID ,count(1) from scott.test group by OBJECT_ID;
     OBJECT_ID   COUNT(1)
    ------------------- ----------
             6          1
             2          1
             5          1
             4          1
             8          1
             3          1
             7          1
            10      87008
             9          1
    9 rows selected.

     可以看到object_id=10的值有87008记录,远远大于该列总记录数的5%

    1.2.  执行查询语句

    执行原有的查询语句,查看执行计划发现走索引,实际上这时表中大部分行的OBJECT_ID都已经被更新为10,所以走索引是不合理的。至于为什么优化器没有选择正确的执行计划是因为执行完"update scott.test set object_id=10 where object_id>10;"后会导致统计信息过期,而又没有重新收集统计信息,优化器并不知道数据发生了变化(未重新收集统计信息),所以仍然走了索引。

    -----不显示记录集,只显示expain+statistics与 set autotrace traceonly等价
    LHR@dlhr> set autot traceonly explain stat  
    
    LHR@dlhr>
    LHR@dlhr> select * from scott.test where object_id=10;
    87008 rows selected.
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2317948335
    -------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |             |     1 |    98 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST        |     1 |    98 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | IDX_TEST_01 |     1 |       |     1   (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    2 - access("OBJECT_ID"=10)
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
          13036  consistent gets
              0  physical reads
              0  redo size
        9839009  bytes sent via SQL*Net to client
          64323  bytes received via SQL*Net from client
           5802  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          87008  rows processed
    
    SQL>
    LHR@dlhr> select /*+ full(test)*/* from scott.test where object_id=10;
    87008 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1357081020
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |     1 |    98 |   347   (1)| 00:00:05 |
    |*  1 |  TABLE ACCESS FULL| TEST |     1 |    98 |   347   (1)| 00:00:05 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("OBJECT_ID"=10)
    
    
    Statistics
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
           6960  consistent gets
              0  physical reads
              0  redo size
        4081838  bytes sent via SQL*Net to client
          64323  bytes received via SQL*Net from client
           5802  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          87008  rows processed
    
    SQL> 

    1.3.  查询上面两个语句的SQL_ID、PLAN_HASH_VALUE

    LHR@dlhr> set autot off
    LHR@dlhr>
    LHR@dlhr> col sql_text format a100
    LHR@dlhr> select sql_text,sql_id,plan_hash_value from v$sql where sql_text like 'select * from scott.test where object_id=10%';
     
    SQL_TEXT                                         SQL_ID                 PLAN_HASH_VALUE
    -------------------------------------------      ---------------    -------------------
    select * from scott.test where object_id=10      cpk9jsg2qt52r              2317948335
     
    LHR@dlhr> select sql_text,sql_id,plan_hash_value from v$sql where sql_text like 'select /*+ full(test)*/* from scott.test where object_id=10%';
     
    SQL_TEXT                                                      SQL_ID   PLAN_HASH_VALUE
    -------------------------------------------------------- ----------------- ------------
    select /*+ full(test)*/* from scott.test where object_id=10   06c2mucgn6t5g  1357081020
     
    --cpk9jsg2qt52r   - 这是原始语句的SQL ID
    --06c2mucgn6t5g   - 这是使用hint的SQL ID
    --1357081020      - 这是需要替换的plan hash value.

    1.4.  把coe_load_sql_profile.sql放在$ORACLE_HOME/下

    1.5.  使用coe_load_sql_profile.sql脚本

    --这两个计划都需要在缓存或AWR中
    --需要以具有DBA权限的用户身份连接,例如SYSTEM
    [ZHLHRSPMDB2:oracle]:/oracle>cd /home/oracle
    [ZHLHRSPMDB2:oracle]:/home/oracle>sqlplus system/oracle
     
    SQL*Plus: Release 11.2.0.4.0 Production on Thu May 26 09:15:14 2016
     Copyright (c) 1982, 2013, Oracle.  All rights reserved.
     
    Connected to:
    Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
    With the Partitioning, Real Application Clusters, OLAP, Data Mining
    and Real Application Testing options
    LHR@dlhr > @/home/oracle/coe_load_sql_profile.sql
    
    Parameter 1:
    ORIGINAL_SQL_ID (required)
    
    Enter value for 1: cpk9jsg2qt52r
    
    Parameter 2:
    MODIFIED_SQL_ID (required)
    
    Enter value for 2: 06c2mucgn6t5g
    
    
         PLAN_HASH_VALUE          AVG_ET_SECS
    -------------------- --------------------
              1357081020                 .052
    
    Parameter 3:
    PLAN_HASH_VALUE (required)
    
    Enter value for 3: 1357081020
    
    Values passed to coe_load_sql_profile:
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ORIGINAL_SQL_ID: "cpk9jsg2qt52r"
    MODIFIED_SQL_ID: "06c2mucgn6t5g"
    PLAN_HASH_VALUE: "1357081020"
    
    SQL>BEGIN
      2    IF :sql_text IS NULL THEN
      3      RAISE_APPLICATION_ERROR(-20100, 'SQL_TEXT for original SQL_ID &&original_sql_id. was not found in memory (gv$sqltext_with_newlines) or AWR (dba_hist_sqltext).');
      4    END IF;
      5  END;
      6  /
    SQL>SET TERM OFF;
    SQL>BEGIN
      2    IF :other_xml IS NULL THEN
      3      RAISE_APPLICATION_ERROR(-20101, 'PLAN for modified SQL_ID &&modified_sql_id. and PHV &&plan_hash_value. was not found in memory (gv$sql_plan) or AWR (dba_hist_sql_plan).');
      4    END IF;
      5  END;
      6  /
    SQL>
    SQL>SET ECHO OFF;
    0001 BEGIN_OUTLINE_DATA
    0002 IGNORE_OPTIM_EMBEDDED_HINTS
    0003 OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
    0004 DB_VERSION('11.2.0.4')
    0005 OPT_PARAM('_b_tree_bitmap_plans' 'false')
    0006 OPT_PARAM('_optim_peek_user_binds' 'false')
    0007 OPT_PARAM('_bloom_filter_enabled' 'false')
    0008 OPT_PARAM('_optimizer_extended_cursor_sharing' 'none')
    0009 OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
    0010 OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
    0011 OPT_PARAM('_optimizer_use_feedback' 'false')
    0012 ALL_ROWS
    0013 OUTLINE_LEAF(@"SEL$1")
    0014 FULL(@"SEL$1" "TEST"@"SEL$1")
    0015 END_OUTLINE_DATA
    dropping staging table "STGTAB_SQLPROF_CPK9JSG2QT52R"
    staging table "STGTAB_SQLPROF_CPK9JSG2QT52R" did not exist
    creating staging table "STGTAB_SQLPROF_CPK9JSG2QT52R"
    packaging new sql profile into staging table "STGTAB_SQLPROF_CPK9JSG2QT52R"
    
    PROFILE_NAME
    ------------------------------
    CPK9JSG2QT52R_1357081020
    SQL>REM
    SQL>REM SQL Profile
    SQL>REM ~~~~~~~~~~~
    SQL>REM
    SQL>SELECT signature, name, category, type, status
      2    FROM dba_sql_profiles WHERE name = :name;
    
               SIGNATURE NAME                                                         CATEGORY                                                     TYPE             STATUS
    -------------------- ------------------------------------------------------------ ------------------------------------------------------------ -------------- ----------------
    10910590721604799112 CPK9JSG2QT52R_1357081020                                     DEFAULT                                                      MANUAL           ENABLED
    SQL>SELECT description
      2    FROM dba_sql_profiles WHERE name = :name;
    
    DESCRIPTION
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    ORIGINAL:CPK9JSG2QT52R MODIFIED:06C2MUCGN6T5G PHV:1357081020 SIGNATURE:10910590721604799112 CREATED BY COE_LOAD_SQL_PROFILE.SQL
    SQL>SET ECHO OFF;
    
    ****************************************************************************
    * Enter SYSTEM password to export staging table STGTAB_SQLPROF_cpk9jsg2qt52r
    ****************************************************************************
    
    Export: Release 11.2.0.4.0 - Production on Fri Oct 16 13:37:08 2020
    
    Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
    
    Password:
    
    Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set
    server uses AL32UTF8 character set (possible charset conversion)
    Note: grants on tables/views/sequences/roles will not be exported
    Note: indexes on tables will not be exported
    Note: constraints on tables will not be exported
    
    About to export specified tables via Conventional Path ...
    . . exporting table   STGTAB_SQLPROF_CPK9JSG2QT52R          1 rows exported
    Export terminated successfully without warnings.
    
    
    If you need to implement this Custom SQL Profile on a similar system,
    import and unpack using these commands:
    
    imp SYSTEM file=STGTAB_SQLPROF_cpk9jsg2qt52r.dmp tables=STGTAB_SQLPROF_cpk9jsg2qt52r ignore=Y
    
    BEGIN
    DBMS_SQLTUNE.UNPACK_STGTAB_SQLPROF (
    profile_name => 'CPK9JSG2QT52R_1357081020',
    replace => TRUE,
    staging_table_name => 'STGTAB_SQLPROF_cpk9jsg2qt52r',
    staging_schema_owner => 'SYSTEM' );
    END;
    /
    
      adding: coe_load_sql_profile_cpk9jsg2qt52r.log (deflated 77%)
      adding: STGTAB_SQLPROF_cpk9jsg2qt52r.dmp (deflated 88%)
      adding: coe_load_sql_profile.log (deflated 62%)
    
    
    SQL>

    1.6.  查看产生的sql profile,此时原语句在不加hint的情况下也走全表扫了

    SQL> select name,CATEGORY,SQL_TEXT from dba_sql_profiles;
    NAME                           CATEGORY   SQL_TEXT
    --------------------------- ---------- ----------------------------------------
    CPK9JSG2QT52R_1357081020      DEFAULT   select * from scott.test where object_id=10
    
    SQL>set line 9999
    SQL> 
    SELECT b.name,
           to_char(d.sql_text) sql_text,
           extractvalue(value(h), '.') as hints
      FROM dba_sql_profiles d,
           SYS.SQLOBJ$DATA A,
           SYS.SQLOBJ$ B,
           TABLE(XMLSEQUENCE(EXTRACT(XMLTYPE(A.COMP_DATA), '/outline_data/hint'))) h
     where a.signature = b.signature
       and a.category = b.category
       and a.obj_type = b.obj_type
       and a.plan_id = b.plan_id
       and D.name = 'CPK9JSG2QT52R_1357081020';

       

    1.7.  验证SQL Profile是否生效

    SYS@dlhr> set autot traceonly explain stat
    SYS@dlhr> select * from scott.test where object_id=10;
    
    
    87010 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1357081020
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |     1 |    98 |   347   (1)| 00:00:05 |
    |*  1 |  TABLE ACCESS FULL| TEST |     1 |    98 |   347   (1)| 00:00:05 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("OBJECT_ID"=10)
    
    Note
    -----
       - SQL profile "CPK9JSG2QT52R_1357081020" used for this statement
    
    
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
           6960  consistent gets
              0  physical reads
              0  redo size
        4081917  bytes sent via SQL*Net to client
          64323  bytes received via SQL*Net from client
           5802  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          87010  rows processed
    
    SQL>
  • 相关阅读:
    [PHP] websocket协议的生成
    [Linux] 解决virtualbox共享文件夹没有访问权限的问题
    [Linux] VirtualBox的ubuntu系统与宿主机共享目录
    [PHP] 框架中.env文件的加载过程
    [PHP] PHP7已经删除了preg_replace的e修饰符
    [日常]解决Connection to `ssl://pecl.php.net:443' failed
    [日常]k8s的前世今生
    [Linux] 利用tcpdump和strace进行debug
    [Go] 使用读写锁对map资源进行安全处理
    [Linux] 使用awk比较两个文件的内容
  • 原文地址:https://www.cnblogs.com/microchuan/p/13826380.html
Copyright © 2020-2023  润新知