zoukankan      html  css  js  c++  java
  • SQL Tuning Advisor简单使用

    SQL Tuning Advision是Oracle提供的一个功能包,可以针对有性能问题的SQL给出优化建议。可以作为调优的辅助手段。


    建立测试表和索引
    create table t_1 as select * from dba_objects;
    create table t_2 as select * from dba_tables;
    create index idx_t_2_ts on t_2(tablespace_name);

    begin
      dbms_stats.gather_table_stats(ownname => user,tabname => 'T_1',cascade => true);
      dbms_stats.gather_table_stats(ownname => user,tabname => 'T_2',cascade => true);
    end;
    /

    假设的SQL。 这些语句运行很慢,需要优化
    -- stmt 1
    select t2.*
      from t_1 t1, t_2 t2
     where t1.owner = t2.owner
       and t1.object_name = t2.table_name
       and t2.blocks > 10
       and t2.tablespace_name = 'USERS';

    -- stmt 2
    select t1.* from t_1 t1 where t1.object_type = 'TABLE';

    使用SQL Tuning Advisor,察看系统提供的优化方案


    Single SQL Statement

    当仅仅需要察看单条语句的时候,可以直接把SQL作为参数创建一个Task

    -- drop a sql tuning task
    begin
    dbms_sqltune.drop_tuning_task(task_name => 'my_sql_tuning_task');
    end;
    /

    -- create a sql tuning task
    declare
    l_task_name varchar2(30);
    l_sqltext clob;
    begin
    l_sqltext := --
    'select t2.*
    from t_1 t1, t_2 t2
    where t1.owner = t2.owner
    and t1.object_name = t2.table_name
    and t2.blocks > :p1
    and t2.tablespace_name = :p2
    ';
    l_task_name := dbms_sqltune.create_tuning_task --
    (sql_text => l_sqltext,
    bind_list => sql_binds(anydata.ConvertNumber(10),
    anydata.ConvertVarchar2('USERS')),
    user_name => user,
    scope => dbms_sqltune.SCOPE_COMPREHENSIVE,
    time_limit => 60,
    task_name => 'my_sql_tuning_task');
    end;
    /

    select l.task_name,l.status from dba_advisor_log l where l.owner = user;

    -- execute a sql tuning task
    begin
    dbms_sqltune.execute_tuning_task(task_name => 'my_sql_tuning_task');
    end;
    /

    -- check the running progress
    select p.sofar, p.totalwork
    from v$advisor_progress p, dba_advisor_log l
    where p.task_id = l.task_id
    and l.task_name = 'my_sql_tuning_task';

    -- display the result
    set long 1000000
    set linesize 100
    select dbms_sqltune.report_tuning_task('my_sql_tuning_task') from dual;

    节选部分结果
    -------------------------------------------------------------------------------
    FINDINGS SECTION (1 finding)
    -------------------------------------------------------------------------------
     
    1- Index Finding (see explain plans section below)
    --------------------------------------------------
      The execution plan of this statement can be improved by creating one or more
      indices.
     
      Recommendation (estimated benefit: 100%)
      ----------------------------------------
      - Consider running the Access Advisor to improve the physical schema design
        or creating the recommended index.
        create index T2_1_12_6_A.IDX$$_7DCA0001 on
        T2_1_12_6_A.T_2('TABLESPACE_NAME','BLOCKS');
     
      - Consider running the Access Advisor to improve the physical schema design
        or creating the recommended index.
        create index T2_1_12_6_A.IDX$$_7DCA0002 on
        T2_1_12_6_A.T_1('OWNER','OBJECT_NAME');
     
      Rationale
      ---------
        Creating the recommended indices significantly improves the execution plan
        of this statement. However, it might be preferable to run "Access Advisor"
        using a representative SQL workload as opposed to a single statement. This
        will allow to get comprehensive index recommendations which takes into
        account index maintenance overhead and additional space consumption.
     
    -------------------------------------------------------------------------------
    EXPLAIN PLANS SECTION
    -------------------------------------------------------------------------------
     
    1- Original
    -----------
    Plan hash value: 3244836478
     
    --------------------------------------------------------------------------------
    | Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)|
    --------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |            |     1 |   250 |   364   (2)|
    |*  1 |  HASH JOIN                   |            |     1 |   250 |   364   (2)|
    |*  2 |   TABLE ACCESS BY INDEX ROWID| T_2        |     1 |   216 |     3   (0)|
    |*  3 |    INDEX RANGE SCAN          | IDX_T_2_TS |    43 |       |     1   (0)|
    |   4 |   TABLE ACCESS FULL          | T_1        |   148K|  4946K|   360   (1)|
    --------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       1 - access("T1"."OWNER"="T2"."OWNER" AND "T1"."OBJECT_NAME"="T2"."TABLE_NAME"
       2 - filter("T2"."BLOCKS">:P1)
       3 - access("T2"."TABLESPACE_NAME"=:P2)
     
    2- Using New Indices
    --------------------
    Plan hash value: 1060650565
     
    --------------------------------------------------------------------------------
    | Id  | Operation                    | Name           | Rows  | Bytes | Cost (%C
    --------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |                |     1 |   250 |     3
    |   1 |  NESTED LOOPS                |                |     1 |   250 |     3
    |   2 |   TABLE ACCESS BY INDEX ROWID| T_2            |     1 |   216 |     2
    |*  3 |    INDEX RANGE SCAN          | IDX$$_7DCA0001 |     1 |       |     1
    |*  4 |   INDEX RANGE SCAN           | IDX$$_7DCA0002 |     1 |    34 |     1
    --------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       3 - access("T2"."TABLESPACE_NAME"=:P2 AND "T2"."BLOCKS">:P1 AND "T2"."BLOCKS"
                  NOT NULL)
       4 - access("T1"."OWNER"="T2"."OWNER" AND "T1"."OBJECT_NAME"="T2"."TABLE_NAME"
     
    -------------------------------------------------------------------------------

    SQL Tuning Set
    当需要对多条语句进行察看的时候,可以使用STS。


    STS可以从多种数据源(CursorCache, AWR, STS)获取SQL,这里我们从Cache中取得我们关心的几条。
    SQL> select sql_id, sql_text from v$sql where lower(sql_text) like 'select t_.*%';
     
    SQL_ID        SQL_TEXT
    ------------- --------------------------------------------------------------------------------
    7rucbfq8vcr7d select t1.*   from t_1 t1    where t1.object_type = 'TABLE'
    588rxmp05xt7g select t2.*   from t_1 t1, t_2 t2  where t1.owner = t2.owner    and t1.object_na

    STS中实际包含的是一些sys.sqlset_row对象,他的属性可以作为筛选的条件
    SQL> desc dbms_sqltune.select_cursor_cache
    Parameter         Type       Mode Default?
    ----------------- ---------- ---- --------
    (RESULT)          SYS.SQLSET              
    BASIC_FILTER      VARCHAR2   IN   Y       
    OBJECT_FILTER     VARCHAR2   IN   Y       
    RANKING_MEASURE1  VARCHAR2   IN   Y       
    RANKING_MEASURE2  VARCHAR2   IN   Y       
    RANKING_MEASURE3  VARCHAR2   IN   Y       
    RESULT_PERCENTAGE NUMBER     IN   Y       
    RESULT_LIMIT      NUMBER     IN   Y       
    ATTRIBUTE_LIST    VARCHAR2   IN   Y       
    -- preview the STS contents
    select t.*
      from table(dbms_sqltune.select_cursor_cache('sql_id in (''588rxmp05xt7g'',''7rucbfq8vcr7d'')')) t;

    找到我们关心的sql_id之后,用这个条件构造STS

    -- create a STS
    begin
    dbms_sqltune.create_sqlset(sqlset_name => 'my_sts');
    end;
    /

    -- load STS using cursor cache
    declare
    l_cur dbms_sqltune.sqlset_cursor;
    begin
    open l_cur for
    select value(t)
    from table(dbms_sqltune.select_cursor_cache('sql_id in (''588rxmp05xt7g'',''7rucbfq8vcr7d'')')) t;

    dbms_sqltune.load_sqlset(sqlset_name => 'my_sts', populate_cursor => l_cur);
    end;
    /

    -- display contents of STS
    select * from table(dbms_sqltune.select_sqlset('my_sts'));

    -- drop a sql tuning task
    begin
    dbms_sqltune.drop_tuning_task(task_name => 'my_sql_tuning_task');
    end;
    /

    -- create a sql tuning task by using STS
    declare
    l_task_name varchar2(30);
    l_sqltext clob;
    begin
    l_task_name := dbms_sqltune.create_tuning_task --
    (sqlset_name => 'my_sts',
    scope => dbms_sqltune.SCOPE_COMPREHENSIVE,
    time_limit => 60,
    task_name => 'my_sql_tuning_task');
    end;
    /

    继续后面的执行和察看步骤(略)

    作者:wait4friend
    Weibo:@wait4friend
    Twitter:@wait4friend
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    深入V8引擎-Time核心方法之win篇(2)
    深入V8引擎-Time核心方法之win篇(1)
    深入V8引擎-Time核心方法之mac篇
    深入V8引擎-Time模块介绍
    深入V8引擎-写在前面
    深入V8引擎-编译启动
    【机器学习】极大似然估计法
    【机器学习】贝叶斯决策论
    【机器学习】贝叶斯决策 实例
    【机器学习】贝叶斯公式
  • 原文地址:https://www.cnblogs.com/wait4friend/p/2334614.html
Copyright © 2011-2022 走看看