zoukankan      html  css  js  c++  java
  • Oracle手工调用STA优化指定SQL

     

    Oracle手工调用STA优化指定SQL

    环境构造

    10:50:58 SYS@zkm(1)> create table scott.zkm as select * from dba_objects;
    
    Table created.
    
    Elapsed: 00:00:01.28
    10:51:19 SYS@zkm(1)> set autotrace traceonly
    10:52:37 SYS@zkm(1)> create index scott.idx_object_id on scott.zkm(object_id) online;
    
    Index created.
    
    Elapsed: 00:00:01.00

    目标SQL

    select /*+ full(a) */ * from scott.zkm a where object_id=1000;

    由于hint的强制关系,该SQL会执行全表扫描,如下:

    10:54:24 SYS@zkm(1)> select /*+ full(a) */ * from scott.zkm a where object_id=1000;
    
    Elapsed: 00:00:00.02
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1571665327
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |     1 |   207 |   366   (1)| 00:00:05 |
    |*  1 |  TABLE ACCESS FULL| ZKM  |     1 |   207 |   366   (1)| 00:00:05 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("OBJECT_ID"=1000)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    Statistics
    ----------------------------------------------------------
              9  recursive calls
              0  db block gets
           1391  consistent gets
           1313  physical reads
              0  redo size
           1628  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

    查询SQL ID。

    col sql_id for a15
    set line 500
    col sql_text for a100
    select sql_id,sql_text from v$sql where sql_text like 'select /*+ full(a) */ * from scott.zkm a where object_id=1000';
    模板复制
    10:56:56 SYS@zkm(27)> col sql_id for a15
    10:57:08 SYS@zkm(27)> set line 500
    10:57:11 SYS@zkm(27)> col sql_text for a100
    10:57:26 SYS@zkm(27)> select sql_id,sql_text from v$sql where sql_text like 'select /*+ full(a) */ * from scott.zkm a where object_id=1000';
    
    SQL_ID          SQL_TEXT
    --------------- ----------------------------------------------------------------------------------------------------
    9ajk015s54vpv   select /*+ full(a) */ * from scott.zkm a where object_id=1000

    跑STA对SQL进行分析。

    DECLARE
      a_tuning_task VARCHAR2(30);
    BEGIN
      a_tuning_task := dbms_sqltune.create_tuning_task(sql_id    => '9ajk015s54vpv',
                                                       task_name => 'sql_profile_test_SQLID');
      dbms_sqltune.execute_tuning_task(a_tuning_task);
    END;
    /
    模板复制
    10:58:40 SYS@zkm(27)> DECLARE
    10:58:41   2    a_tuning_task VARCHAR2(30);
    10:58:41   3  BEGIN
    10:58:41   4    a_tuning_task := dbms_sqltune.create_tuning_task(sql_id    => '9ajk015s54vpv',
    10:58:41   5                                                     task_name => 'sql_profile_test_SQLID');
    10:58:41   6    dbms_sqltune.execute_tuning_task(a_tuning_task);
    10:58:41   7  END;
    10:58:41   8  /
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:02.56

    或者:

    DECLARE
      a_tuning_task VARCHAR2(30);
    BEGIN
      a_tuning_task := dbms_sqltune.create_tuning_task(sql_text    => 'select /*+ full(a) */ * from scott.zkm a where object_id=1000',
                                                       task_name => 'sql_profile_test_SQLID');
      dbms_sqltune.execute_tuning_task(a_tuning_task);
    END;
    /

    使用PLSQL工具查看优化建议报告(用sqlplus格式会乱)。

    SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( 'sql_profile_test_SQLID') from DUAL;

    GENERAL INFORMATION SECTION
    -------------------------------------------------------------------------------
    Tuning Task Name   : sql_profile_test_SQLID
    Tuning Task Owner  : SYS
    Workload Type      : Single SQL Statement
    Scope              : COMPREHENSIVE
    Time Limit(seconds): 1800
    Completion Status  : COMPLETED
    Started at         : 09/01/2020 10:58:42
    Completed at       : 09/01/2020 10:58:44
    
    -------------------------------------------------------------------------------
    Schema Name: SYS
    SQL ID     : 9ajk015s54vpv
    SQL Text   : select /*+ full(a) */ * from scott.zkm a where object_id=1000
    
    -------------------------------------------------------------------------------
    FINDINGS SECTION (2 findings)
    -------------------------------------------------------------------------------
    
    1- Statistics Finding
    ---------------------
      Table "SCOTT"."ZKM" was not analyzed.
    
      Recommendation
      --------------
      - Consider collecting optimizer statistics for this table.
        execute dbms_stats.gather_table_stats(ownname => 'SCOTT', tabname =>
                'ZKM', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
                method_opt => 'FOR ALL COLUMNS SIZE AUTO');
    
      Rationale
      ---------
        The optimizer requires up-to-date statistics for the table in order to
        select a good execution plan.
    
    2- SQL Profile Finding (see explain plans section below)
    --------------------------------------------------------
      A potentially better execution plan was found for this statement.
    
      Recommendation (estimated benefit: 99.77%)
      ------------------------------------------
      - Consider accepting the recommended SQL profile.
        execute dbms_sqltune.accept_sql_profile(task_name =>
                'sql_profile_test_SQLID', task_owner => 'SYS', replace => TRUE);
    
      Validation results
      ------------------
      The SQL profile was tested by executing both its plan and the original plan
      and measuring their respective execution statistics. A plan may have been
      only partially executed if the other could be run to completion in less time.
    
                               Original Plan  With SQL Profile  % Improved
                               -------------  ----------------  ----------
      Completion Status:            COMPLETE          COMPLETE
      Elapsed Time (s):             .002195           .000006      99.72 %
      CPU Time (s):                 .002092           .000006      99.71 %
      User I/O Time (s):                  0                 0 
      Buffer Gets:                     1318                 3      99.77 %
      Physical Read Requests:             0                 0 
      Physical Write Requests:            0                 0 
      Physical Read Bytes:                0                 0 
      Physical Write Bytes:               0                 0 
      Rows Processed:                     1                 1 
      Fetches:                            1                 1 
      Executions:                         1                 1 
    
      Notes
      -----
      1. Statistics for the original plan were averaged over 10 executions.
      2. Statistics for the SQL profile plan were averaged over 10 executions.
    
    -------------------------------------------------------------------------------
    EXPLAIN PLANS SECTION
    -------------------------------------------------------------------------------
    
    1- Original With Adjusted Cost
    ------------------------------
    Plan hash value: 1571665327
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |     2 |   206 |   366   (1)| 00:00:05 |
    |*  1 |  TABLE ACCESS FULL| ZKM  |     2 |   206 |   366   (1)| 00:00:05 |
    --------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       1 - filter("OBJECT_ID"=1000)
    
    2- Using SQL Profile
    --------------------
    Plan hash value: 3532417104
    
    ---------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |               |     2 |   206 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| ZKM           |     2 |   206 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | IDX_OBJECT_ID |     2 |       |     1   (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       2 - access("OBJECT_ID"=1000)
    
    -------------------------------------------------------------------------------
    优化报告

    根据优化报告,

    第一个建议是收集统计信息:

    1- Statistics Finding
    ---------------------
      Table "SCOTT"."ZKM" was not analyzed.
    
      Recommendation
      --------------
      - Consider collecting optimizer statistics for this table.
        execute dbms_stats.gather_table_stats(ownname => 'SCOTT', tabname =>
                'ZKM', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
                method_opt => 'FOR ALL COLUMNS SIZE AUTO');
    
      Rationale
      ---------
        The optimizer requires up-to-date statistics for the table in order to
        select a good execution plan.

    第二个建议你使用sql profile固定执行计划,是使用索引的执行计划:

    2- SQL Profile Finding (see explain plans section below)
    --------------------------------------------------------
      A potentially better execution plan was found for this statement.
    
      Recommendation (estimated benefit: 99.77%)
      ------------------------------------------
      - Consider accepting the recommended SQL profile.
        execute dbms_sqltune.accept_sql_profile(task_name =>
                'sql_profile_test_SQLID', task_owner => 'SYS', replace => TRUE);
    
    2- Using SQL Profile
    --------------------
    Plan hash value: 3532417104
    
    ---------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |               |     2 |   206 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| ZKM           |     2 |   206 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | IDX_OBJECT_ID |     2 |       |     1   (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       2 - access("OBJECT_ID"=1000)
    
    -------------------------------------------------------------------------------

     

    执行建议

    1. execute dbms_stats.gather_table_stats(ownname => 'SCOTT', tabname => 'ZKM', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,method_opt => 'FOR ALL COLUMNS SIZE AUTO');
    2. execute dbms_sqltune.accept_sql_profile(task_name => 'sql_profile_test_SQLID', task_owner => 'SYS', replace => TRUE);
    11:27:16 SYS@zkm(23)> execute dbms_stats.gather_table_stats(ownname => 'SCOTT', tabname => 'ZKM', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,method_opt => 'FOR ALL COLUMNS SIZE AUTO');
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.49
    11:27:31 SYS@zkm(23)> execute dbms_sqltune.accept_sql_profile(task_name => 'sql_profile_test_SQLID', task_owner => 'SYS', replace => TRUE);
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.21

    再次执行SQL,已经使用了索引:

    11:28:23 SYS@zkm(1)> select /*+ full(a) */ * from scott.zkm a where object_id=1000;
    
    Elapsed: 00:00:00.03
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 3532417104
    
    ---------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |               |     2 |   196 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| ZKM           |     2 |   196 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | IDX_OBJECT_ID |     2 |       |     1   (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("OBJECT_ID"=1000)
    
    Note
    -----
       - SQL profile "SYS_SQLPROF_017447b4e5170000" used for this statement
    
    
    Statistics
    ----------------------------------------------------------
             36  recursive calls
              0  db block gets
             15  consistent gets
              1  physical reads
              0  redo size
           1631  bytes sent via SQL*Net to client
            523  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
              1  rows processed

    从这里可以看出,SQL profile的优先级高于HINT。

    回退

    若是发现应用建议后,没有改善情况或者情况恶化,可以如下回退:

    col name for a35
    col sql_text for a100
    set line 500
    select name,SQL_TEXT,STATUS from dba_sql_profiles;
    模板复制
    11:33:54 SYS@zkm(27)> col name for a35
    11:34:00 SYS@zkm(27)> col sql_text for a100
    11:34:06 SYS@zkm(27)> set line 500
    11:34:08 SYS@zkm(27)> select name,SQL_TEXT,STATUS from dba_sql_profiles;
    
    NAME                                SQL_TEXT                                                                                             STATUS
    ----------------------------------- ---------------------------------------------------------------------------------------------------- ------------------------
    SYS_SQLPROF_017447b4e5170000        select /*+ full(a) */ * from scott.zkm a where object_id=1000                                        ENABLED
    
    
    
    Elapsed: 00:00:00.00
    
    11:34:39 SYS@zkm(27)> execute dbms_sqltune.drop_sql_profile('SYS_SQLPROF_017447b4e5170000');
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.01
    
    11:34:52 SYS@zkm(1)> select /*+ full(a) */ * from scott.zkm a where object_id=1000;
    
    Elapsed: 00:00:00.01
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1571665327
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |     1 |    98 |   366   (1)| 00:00:05 |
    |*  1 |  TABLE ACCESS FULL| ZKM  |     1 |    98 |   366   (1)| 00:00:05 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    exec dbms_sqltune.execute_tuning_task('SYS_AUTO_SQL_TUNING_TASK');
    select dbms_sqltune.report_tuning_task('SYS_AUTO_SQL_TUNING_TASK') from dual;
    
    
    
    ---------------------------------------------------
    
       1 - filter("OBJECT_ID"=1000)
    
    
    Statistics
    ----------------------------------------------------------
              5  recursive calls
              0  db block gets
           1319  consistent gets
              0  physical reads
              0  redo size
           1628  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

     

    删除STA任务

    最后记得删除STA任务。

    11:34:53 SYS@zkm(1)> exec dbms_sqltune.drop_TUNING_TASK( 'sql_profile_test_SQLID');
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.05

    其他

    对于系统每日自动运行的STA任务,如果不需要可以禁用,必要时可以手工运行。

    exec dbms_sqltune.execute_tuning_task('SYS_AUTO_SQL_TUNING_TASK');
    select dbms_sqltune.report_tuning_task('SYS_AUTO_SQL_TUNING_TASK') from dual;
  • 相关阅读:
    js对象数组(JSON) 根据某个共同字段 分组
    一个 函数 用来转化esSearch 的range 条件
    关于 vuex 报错 Do not mutate vuex store state outside mutation handlers.
    android listview 重用view导致的选择混乱问题
    android SDK和ADT的更新
    Android中adb push和adb install的使用区别
    pycharm中添加扩展工具pylint
    su Authentication failure解决
    Putty以及adb网络调试
    有关android源码编译的几个问题
  • 原文地址:https://www.cnblogs.com/PiscesCanon/p/13594875.html
Copyright © 2011-2022 走看看