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;
  • 相关阅读:
    [转]Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简述及技术选型介绍
    推荐一个windows系统的下载和安装的网址:win7之家
    [转]vue调试工具vue-devtools安装及使用(亲测有效,望采纳)
    [转]Error: Node Sass does not yet support your current environment: Windows 64-bit
    [转]升级/重装win10系统--提示无法验证密钥的解决办法
    Sólo le pido a Dios
    Composer 语法中的^符号意思
    服务器上传的目录索引一定要关闭
    [SAP] CloudWatch
    [SAA] 32. Data Engineering
  • 原文地址:https://www.cnblogs.com/PiscesCanon/p/13594875.html
Copyright © 2011-2022 走看看