使用DBMS_SQLTUNE的Sql Tuning Advisor优化SQL

来源:互联网 发布:淘宝旗舰店会有假货吗 编辑:程序博客网 时间:2024/05/14 21:45

在10.2.0.1和之后的版本中Oracle支持用DBMS_SQLTUNE运行Sql Tuning Advisor 对SQL进行调优,下面就用一个实例介绍下这个功能:
   1.需要调优的SQL所在的相应的用户必须有Advisor权限(如果在OEM中使用SQL Tuning Advisor,需要要赋予select_catalog_role 角色),本例使用的是Oracle自带的SH用户:
      SQL> grant advisor  to sh;
      Grant succeeded.
     
      SQL> grant SELECT_CATALOG_ROLE TO sh;
      Grant succeeded.
     
      SQL> grant execute  on dbms_sqltune to sh;
      Grant succeeded.
     
   2.创建调优任务:
      SQL> DECLARE
      2    my_task_name VARCHAR2(30);
      3    my_sqltext CLOB;
      4  BEGIN
      5    my_sqltext := 'SELECT * '   ||
      6                  'FROM sales ' || 'WHERE prod_id = 10 AND ' || 'cust_id = 100 ';
      7 
      8    my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
      9                             sql_text => my_sqltext,
      10                             user_name => 'SH',
      11                             scope => 'COMPREHENSIVE',---表示建议中有SQL Profiling 分析的内容
      12                             time_limit => 60,---任务运行的时间(s)
      13                             task_name => 'TEST_sql_tuning_task',
      14                             description => 'Task to tune a query on a specified PRODUCT');
      15  end;
      16  /


   3.查看SH用户下调优任务:
     SQL> select task_name from dba_advisor_log where owner='SH';
     TASK_NAME
     ------------------------------
     TEST_sql_tuning_task      
   
   4.执行调优任务:
     SQL> Execute dbms_sqltune.Execute_tuning_task (task_name => 'TEST_sql_tuning_task');
     PL/SQL procedure successfully completed.
    
   5.查看调优任务的状态:
     SQL> select status from dba_advisor_log where task_name='TEST_sql_tuning_task';
     STATUS
     -----------
     COMPLETED
    
   6.通过调用dbms_sqltune.report_tuning_task可以查询调优的结果,不过在查询结果之前,得设置sqlplus的环境,如果不设置,则查询的结果出不来
  
     SQL> set long 999999
     SQL> set LONGCHUNKSIZE 999999
     SQL> set serveroutput on size 999999
     SQL> set linesize 200
     SQL> select dbms_sqltune.report_tuning_task('TEST_sql_tuning_task') from dual;
    
     DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING_TASK')
     --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     GENERAL INFORMATION SECTION
     -------------------------------------------------------------------------------
     Tuning Task Name                  : TEST_sql_tuning_task
     Tuning Task Owner                 : SH
     Scope                             : COMPREHENSIVE
     Time Limit(seconds)               : 60
     Completion Status                 : COMPLETED
     Started at                        : 07/24/2013 10:41:00
     Completed at                      : 07/24/2013 10:41:01
     Number of Index Findings          : 1
    
    
     DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING_TASK')
     --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     -------------------------------------------------------------------------------
     Schema Name: SH
     SQL ID     : 9bxw71yp99fr6
     SQL Text   : SELECT * FROM sales WHERE prod_id = 10 AND cust_id = 100
    
     -------------------------------------------------------------------------------
     FINDINGS SECTION (1 finding)
     -------------------------------------------------------------------------------
    
     1- Index Finding (see explain plans section below)
     --------------------------------------------------
    
     DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING_TASK')
     --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
       The execution plan of this statement can be improved by creating one or more
       indices.
    
       Recommendation (estimated benefit: 93.1%)
       -----------------------------------------
       - Consider running the Access Advisor to improve the physical schema design
         or creating the recommended index.
         create index SH.IDX$$_00490001 on SH.SALES("CUST_ID","PROD_ID");---建议对SALES表创建一个CUST_ID和PROD_ID的联合索引
    
       Rationale
       ---------
    
     DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING_TASK')
     --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
         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
    
     DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING_TASK')
     --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     -----------
     Plan hash value: 811666046
    
     ---------------------------------------------------------------------------------------------------------------------
     | Id  | Operation                          | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
     ---------------------------------------------------------------------------------------------------------------------
     |   0 | SELECT STATEMENT                   |                |     1 |    29 |    58   (0)| 00:00:01 |       |       |
     |   1 |  PARTITION RANGE ALL               |                |     1 |    29 |    58   (0)| 00:00:01 |     1 |    28 |
     |   2 |   TABLE ACCESS BY LOCAL INDEX ROWID| SALES          |     1 |    29 |    58   (0)| 00:00:01 |     1 |    28 |
     |   3 |    BITMAP CONVERSION TO ROWIDS     |                |       |       |            |          |       |       |
     |   4 |     BITMAP AND                     |                |       |       |            |          |       |       |
    
     DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING_TASK')
     --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     |*  5 |      BITMAP INDEX SINGLE VALUE     | SALES_CUST_BIX |       |       |            |          |     1 |    28 |
     |*  6 |      BITMAP INDEX SINGLE VALUE     | SALES_PROD_BIX |       |       |            |          |     1 |    28 |
     ---------------------------------------------------------------------------------------------------------------------
    
     Predicate Information (identified by operation id):
     ---------------------------------------------------
    
        5 - access("CUST_ID"=100)
        6 - access("PROD_ID"=10)
    
     2- Using New Indices
    
     DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING_TASK')
     --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     --------------------
     Plan hash value: 2738539909
    
     ---------------------------------------------------------------------------------------------------------------------
     | Id  | Operation                          | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
     ---------------------------------------------------------------------------------------------------------------------
     |   0 | SELECT STATEMENT                   |                |     1 |    29 |     4   (0)| 00:00:01 |       |       |
     |   1 |  TABLE ACCESS BY GLOBAL INDEX ROWID| SALES          |     1 |    29 |     4   (0)| 00:00:01 | ROWID | ROWID |
     |*  2 |   INDEX RANGE SCAN                 | IDX$$_00490001 |     1 |       |     3   (0)| 00:00:01 |       |       |
     ---------------------------------------------------------------------------------------------------------------------
    
    
     DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING_TASK')
     --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     Predicate Information (identified by operation id):
     ---------------------------------------------------
    
        2 - access("CUST_ID"=100 AND "PROD_ID"=10)
    
     -------------------------------------------------------------------------------
    
    7.查看SALES表中的索引并建立联合索引:
      SQL> select INDEX_NAME,index_type from user_indexes where table_name='SALES';
      INDEX_NAME                     INDEX_TYPE
      ------------------------------ ---------------------------
      SALES_PROD_BIX                 BITMAP
      SALES_CUST_BIX                  BITMAP
      SALES_TIME_BIX                  BITMAP
      SALES_CHANNEL_BIX         BITMAP
      SALES_PROMO_BIX              BITMAP
     
      发现是为图索引,下面建立联合索引
     
      SQL> create index idx_s on SH.SALES("CUST_ID","PROD_ID");
     
      SQL> SELECT * FROM sales WHERE prod_id = 10 AND cust_id = 100;

      no rows selected
     
     
      Execution Plan
      ----------------------------------------------------------
      Plan hash value: 3410910736
     
      ------------------------------------------------------------------------------------------------------------
      | Id  | Operation                          | Name  | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
      ------------------------------------------------------------------------------------------------------------
      |   0 | SELECT STATEMENT                   |       |     1 |    29 |     4   (0)| 00:00:01 |       |       |
      |   1 |  TABLE ACCESS BY GLOBAL INDEX ROWID| SALES |     1 |    29 |     4   (0)| 00:00:01 | ROWID | ROWID |
      |*  2 |   INDEX RANGE SCAN                 | IDX_S |     1 |       |     3   (0)| 00:00:01 |       |       |
      ------------------------------------------------------------------------------------------------------------
     
      Predicate Information (identified by operation id):
      ---------------------------------------------------
     
         2 - access("CUST_ID"=100 AND "PROD_ID"=10)
        
         这里可以看到走的是联合索引也就是ADVISOR建议的。

原创粉丝点击