zoukankan      html  css  js  c++  java
  • Using Oracle 10g Tuning Utilities

    Oracle is always improving life for DBAs and developers with each release of the RDBMS. 10g has many new features to help troubleshoot and tune the database. Starting with 10g, Oracle has introduced Advisors. These Advisors are part of the ADDM (Automatic Database Diagnostic Monitor) and run in the background as long as the parameter STATICS_LEVEL is set to at least TYPICAL, which is the default for a new database installed. Here we will discuss some of the more common utilities used and how they can help.

    DBMS_SQLTUNE package

    This package is of great help in tuning SQL statements. Simply put, it analyzes the SQL statement and gives back recommendations on how to improve the statements performance if it finds a better way. It will show you the current execution plan as well as the execution plan if you were to make the recommended changes. It will give the reasoning for the recommendation and even give you the commands to implement the recommended change. This is a great tool to use in developing new applications as well as troubleshooting existing ones in a production environment.

    This package will let you create SQL profiles. SQL profiling analyzes a statement and offers a better Execution Plan if one is available. You can apply this plan to the SQL profile and SQL will use this plan the next time it is run. This can give better performance without changing application code.

    You can use this to compare SQL statements using tuning sets.

    Let’s look at some of the components that make up the DBMS_SQLTUNE package. Please see Oracle documentation for all components in the DBMS_SQLTUNE package. I will show and explain the most commonly used procedures.

    • CREATE_TUNING_TASK – This function will create a new tuning task and return the name of the task. A generated name will be given if one is not specified. Some of the inputs are:
      • SQL_ID – This is the SQL_ID of an existing SQL statement in the SGA. This id can be found in V$SQL, V$SQLTEXT, V$SESSION and a few other V$ views. You cannot use this along with SQL_TEXT.
      • SQL_TEXT – This can be used to enter the SQL statement manually if it is not in the SGA. You cannot use this along with SQL_ID.
      • BIND_LIST – Pass in any bind variables for SQL statement. Type of input is SQL_BINDS.
      • USER_NAME – The owner of the SQL statement.
      • SCOPE – This sets the scope and there are two different settings.
        • LIMITED – This makes recommendations based on analysis of the following: SQL structure, statistics and access path.
        • COMPREHINSIVE – This makes recommendations based on all analysis of LIMITED and SQL Profiling. Note: This is the most resource intensive and can take much time to complete. A TIME_LIMIT setting can be specified to limit how long it should analyze.
      • TIME_LIMIT – Time in seconds of how long a COMPREHENSIZE analysis can run. The default is 30 minutes if not set. That does not mean the analysis will run that long, just that is the limit of how long it can run. If the analysis hasn’t completed by the time limit, it will give recommendations on what it has found so far.
      • TASK_NAME – Name given to identify a task.
      • DESCRIPTION – To give a description of the task.
    • DROP_TUNING_TASK – This procedure drops a tuning task that has been created. It only takes one input parameter.
      • TASK_NAME – This is the name of the task created with the CREATE_TUNING_TASK function.
    • EXECUTE_TUNING_TASK – Will run the created tuning task.
      • TASK_NAME – Name of the task created from CREATE_TUNING_TASK function.
    • CANCEL_TUNING_TASK – Cancel a task that is currently running.
      • TASK_NAME – Name of the task running from EXECUTE_TUNING_TASK.
    • INTERRUPT_TUNING_TASK – This will interrupt an executing task and allow you to query data collected up to the interruption.
      • TASK_NAME – Name of the task running from EXECUTE_TUNING_TASK.
    • RESET_TUNING_TASK – Reset a tuning task to its initial state and delete all data collected.
      • TASK_NAME – Name of the task created from CREATE_TUNING_TASK function.
    • RESUME_TUNING_TASK – Resume an interrupted tuning task. This can only be used with tuning sets.
      • TASK_NAME – Name of the task created from CREATE_TUNING_TASK function.
    • REPORT_TUNING_TASK – This will return a report of what it found and offer any recommendations from the analysis.
      • TASK_NAME – Name of the task executed from EXECUTE_TUNING_TASK procedure.
      • TYPE – Type of report to produce, values are: HTML, XML and TEXT. Default is TEXT.
      • LEVEL – Level of detail for the report, values are:
        • BASIC – Gives General information section, Findings and Explain Plans.
        • TYPICAL – Same as BASIC except with SQL profiling information, recommendations and more detailed Explain Plans. This is the default.
        • ALL – Same as TYPICAL except with detailed object information and very detailed Explain Plan.
      • SECTION – What section to show in the report; values are:
        • FINDINGS – Report only the Finding section.
        • PLANS – Report only the Explain Plan section for current SQL and any recommendations.
        • INFORMATION – Report only the General Information section.
        • ERRORS – Only report Error section if found, otherwise only General Information shown.
        • ALL – Report every section. This is the default.
    • SCRIPT_TUNING_TASK – This function will output PL/SQL commands to implement recommendations from an executed tuning task.
      • TASK_NAME – Name of the task created from CREATE_TUNING_TASK function.
      • REC_TYPE – Types of recommendations to include. These can be separated by commas (e.g. ‘MyTaskName’,’INDEXES,STATISTICS’), values are:
        • PROFILES – Only commands to implement recommended SQL Profiles.
        • STATISTICS – Only commands for stale and/or missing statistics.
        • INDEXES – Only commands for index recommendations.
        • ALL – Commands for all recommendations; this is the default.

    There are more procedures in the DBMS_SQLTUNE package that I will talk about later in this chapter. I want to show you how to use this tool for tuning before going into detail about the other procedures. Now, enough of the boring descriptions and lets start using this tool.

    Let’s create a small sample table with data.

    Create_test_table.sql
    drop table tb
    /
    create table tb (tb_seq number, 
    		var_col1 varchar2(32), 
    		var_col2 varchar2(64), 
    		date_col date)
    /
    drop sequence tb_num_seq
    /
    create sequence tb_num_seq start with 1
    /
    
    declare
       cnt number := 0;
    begin
       for cnt in 1 .. 100
        loop
          insert into tb values (tb_num_seq.nextval,
    			     'Test',
    			     'Description for test',
    			     sysdate);
       end loop;
    end;
    /
    commit
    /

    In this example, we will tune a single SQL statement.

    First, we create a new Tuning Task named ‘Useless Task’ using the CREATE_TUNING_TASK function.

    DECLARE
      my_task_name varchar2(30);
      sql_txt clob;
    
    BEGIN
    
    sql_txt := 'select var_col2 from tb where TB_seq = :b1 and var_col2 =  :b2';
    
      my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
                               sql_text => sql_txt,
    --                           user_name => 'MYUSER', -- if sql owner is different than current session
                               scope => 'COMPREHENSIVE',
                               time_limit => 300,  -- 5 minute time limit
                               task_name => 'Useless_Task',
                               description => 'Tune Useless Query Task');
    END;
    /

    Once run, the ‘Useless Task’ will be created. We must now execute the newly created task.

    SQL> execute dbms_sqltune.execute_tuning_task (task_name => 'Useless_Task’);

    Note: If this task is running too long for your liking, you can ‘execute dbms_sqltune.interrupt_tuning_task(‘Useless Task’);’ from another session.

    When the procedure completes, you can execute the following SQL to return a report.

    SQL> set long 5000  --  must set this to display output
    SQL> set pagesize 0
    SQL> select dbms_sqltune.report_tuning_task('Useless_Task') from dual;

    Below is the output of the report. I numbered the lines in the output for readability.

         1  GENERAL INFORMATION SECTION
         2  -------------------------------------------------------------------------------
         3  Tuning Task Name                  : Useless_Task
         4  Tuning Task Owner                 : MYUSER
         5  Scope                             : COMPREHENSIVE
         6  Time Limit(seconds)               : 300
         7  Completion Status                 : COMPLETED
         8  Started at                        : 01/26/2007 14:25:37
         9  Completed at                      : 01/26/2007 14:25:38
        10  Number of Statistic Findings      : 1
        11  Number of Index Findings          : 1
        12
        13  -------------------------------------------------------------------------------
        14  Schema Name: MYUSER
        15  SQL ID     : guu7ppk7pu1a5
        16  SQL Text   : select var_col2 from tb where TB_seq = :b1 and var_col2 =  :b2
        17
        18  -------------------------------------------------------------------------------
        19  FINDINGS SECTION (2 findings)
        20  -------------------------------------------------------------------------------
        21
        22  1- Statistics Finding
        23  ---------------------
        24    Table "MYUSER"."TB" was not analyzed.
        25
        26    Recommendation
        27    --------------
        28    - Consider collecting optimizer statistics for this table.
        29      execute dbms_stats.gather_table_stats(ownname => 'MYUSER', tabname =>
        30              'TB', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, 
        31             method_opt => 'FOR ALL COLUMNS SIZE AUTO');
        32
        33    Rationale
        34    ---------
        35      The optimizer requires up-to-date statistics for the table in order to
        36      select a good execution plan.
        37
        38  2- Index Finding (see explain plans section below)
        39  --------------------------------------------------
        40    The execution plan of this statement can be improved by creating one or more
        41    indices.
        42
        43    Recommendation (estimated benefit: 100%)
        44    ----------------------------------------
        45    - Consider running the Access Advisor to improve the physical schema design
        46      or creating the recommended index.
        47      create index MYUSER.IDX$$_51CC0001 on MYUSER.TB('TB_SEQ','VAR_COL2');
        48
        49    Rationale
        50    ---------
        51      Creating the recommended indices significantly improves the execution plan
        52      of this statement. However, it might be preferable to run "Access Advisor"
        53      using a representative SQL workload as opposed to a single statement. This
        54      will allow to get comprehensive index recommendations which takes into
        55      account index maintenance overhead and additional space consumption.
        56
        57  -------------------------------------------------------------------------------
        58  EXPLAIN PLANS SECTION
        59  -------------------------------------------------------------------------------
        60
        61  1- Original
        62  -----------
        63  Plan hash value: 1750851749
        64
        65  --------------------------------------------------------------------------
        66  | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
        67  --------------------------------------------------------------------------
        68  |   0 | SELECT STATEMENT  |      |     1 |    47 |     3   (0)| 00:00:01 |
        69  |*  1 |  TABLE ACCESS FULL| TB   |     1 |    47 |     3   (0)| 00:00:01 |
        70  --------------------------------------------------------------------------
        71
        72  Predicate Information (identified by operation id):
        73  ---------------------------------------------------
        74
        75     1 - filter("TB_SEQ"=:B1 AND "VAR_COL2"=:B2)
        76
        77  2- Using New Indices
        78  --------------------
        79  Plan hash value: 3914465704
        80
        81  --------------------------------------------------------------------------------
        82  ---
        83  | Id  | Operation        | Name           | Rows  | Bytes | Cost (%CPU)| Time
        84    |
        85  --------------------------------------------------------------------------------
        86  ---
        87  |   0 | SELECT STATEMENT |                |     1 |    47 |     1   (0)| 00:00:0
        88  1 |
        89  |*  1 |  INDEX RANGE SCAN| IDX$$_51CC0001 |     1 |    47 |     1   (0)| 00:00:0
        90  1 |
        91  --------------------------------------------------------------------------------
        92  ---
        93
        94  Predicate Information (identified by operation id):
        95  ---------------------------------------------------
        96
        97     1 - access("TB_SEQ"=:B1 AND "VAR_COL2"=:B2)
        98
        99 	-------------------------------------------------------------------------------

    Lines 1 through 16 are the General Information section. This will show a summery of analysis.

    Line 7 will give the status of the analysis.

    7  Completion Status                 : COMPLETED

    In this case the analysis completed; it would show INTERRUPTED if you executed INTERRUPT_TUNING_TASK during execution of analysis.

    The following shows under the General Information section if the task ends before the analysis completed due to its running longer than the TIME_LIMIT set in CREATE_TUNING_TASK. A similar error would show for INTERRUPTED or if the execution of the task was cancelled using CANCEL_TUNING_TASK..

    ERRORS SECTION

    -------------------------------------------------------------------------------
    - The current operation was interrupted because it timed out.
    
    -------------------------------------------------------------------------------

    Line 15 is the sql id that can be linked to some of the V$ views.

    15  SQL ID     : guu7ppk7pu1a5

    Lines 19 through 55 are the Findings section. This will tell what it has found during the analysis. We can see that there are two findings.

    Line 43 tells us potentially how much can be gained by implementing the recommendation.

    Lines 29 and 31 give the SQL to implement the first set of recommendations.

     	29    execute dbms_stats.gather_table_stats(ownname => 'MYUSER', tabname =>
     	30            'TB', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, 
    	31             method_opt => 'FOR ALL COLUMNS SIZE AUTO');

    Line 47 gives the SQL to implement the second set of recommendations.

    Lines 61 on show the Explain Plan of the original statement. And here is the great part, lines 77 on shows what the new plan will look like if you implement the recommendations.

    You can see the original plan shows a cost of 3 and the new one is 1. An index is obvious in this case to improve this statement, but it may be to your advantage to implement one recommendation at a time and run the analysis again because the analysis may have better recommendations after you implement the first. In this case, the analysis pointed to the table not having any statistics. This can affect the index it recommends.

    Let’s implement the first recommendation.

    Note: Always check the SQL before implementing, never assume it to always be correct. Besides, you may want to name the objects differently and maybe place them in a different tablespace. As in this example we have to remove the single quotes from ‘on MYUSER.TB('TB_SEQ');’ in order to create the correct index.

    SQL> execute dbms_stats.gather_table_stats(ownname => 'MYUSER', tabname =>
     	'TB', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, 
      method_opt => 'FOR ALL COLUMNS SIZE AUTO');

    Now if we execute, then run the report again, we will see the index recommendation is different. That is because it now knows what the data looks like.

     create index MYUSER.IDX$$_51EA0001 on MYUSER.TB('TB_SEQ');

    Now that you’ve seen a basic example, let’s look at how to create another tuning task by modifying the previous one. We can use the same task name if we drop it first or use a different name; this way we can compare different tasks.

    This example is using bind variables.

    tuning2.sql 
         1  DECLARE
         2    my_task_name varchar2(30);
         3    sql_txt clob;
         4
         5  BEGIN
         6
         7  sql_txt := 'select var_col2 from tb where TB_seq = :b1 and var_col2 =  :b2';
         8
         9    my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
        10                            sql_text => sql_txt,
        11                            bind_list => sql_binds(anydata.ConvertNumber(91),anydata.ConvertVarchar2('Test')),
        12  --                           user_name => 'MYUSER', -- if sql owner is different than current session
        13                             scope => 'COMPREHENSIVE',
        14                             time_limit => 300,
        15                             task_name => 'Useless_Task_WBinds',
        16                             description => 'Tune Useless Query Task Using Binds');
        17  END;
        18  /

    Line 11 is where bind variables are entered using bind_list.

    In the above we are entering two bind variables, anydata.ConvertNumber(91) is entering the number 91 and anydata.ConvertVarchar2(‘Test’) is a varchar value of ‘Test’. I’m not going to go into the details of SQL_BINDS, you can find more information in Oracle documentation, but below is a list of input functions.

    	ConvertNumber(IN NUMBER) RETURN AnyData
    	ConvertDate(IN DATE) RETURN AnyData
    	ConvertChar(IN CHAR) RETURN AnyData
    	ConvertVarchar(IN VARCHAR) RETURN AnyData
    	ConvertVarchar2(IN VARCHAR2) RETURN AnyData
    	ConvertRaw(IN RAW) RETURN AnyData
    	ConvertBlob(IN BLOB) RETURN AnyData
    	ConvertClob(IN CLOB) RETURN AnyData
    	ConvertBfile(IN BFILE) RETURN AnyData
    	ConvertObject(IN "<object_type>") RETURN AnyData
    	ConvertRef(IN REF "<object_type>") RETURN AnyData
    	ConvertCollection(IN "<COLLECTION_1>") RETURN AnyData

    Once, the above is created and executed (remember that this task will have to be dropped or a new name given before this task is created), the report will show a new recommendation.

    Recommendation (estimated benefit: 100%)
     ----------------------------------------
     - Consider running the Access Advisor to improve the physical schema design
       or creating the recommended index.
       create index MYUSER.IDX$$_52AD0001 on MYUSER.TB('VAR_COL2');

    Now let’s change the bind data for the var_col2 column to a value that is in the table. So anydata.ConvertVarchar2(‘Test’) is changed to anydata.ConvertVarchar2(‘Description for test’). Let’s recreate the task, execute and run the report.

    -------------------------------------------------------------------------------
    There are no recommendations to improve the statement.
    
    -------------------------------------------------------------------------------

    Now we see that there aren’t any recommendations. From this example, you can see how bind data can make a difference to the findings.

  • 相关阅读:
    OC面向对象—封装
    OC内存管理
    OC方法和文件编译
    OC语言基础知识
    OC语言前期准备
    C语言指针基础
    C语言字符串
    C语言数组
    C语言内存分析
    C语言函数
  • 原文地址:https://www.cnblogs.com/tracy/p/2055271.html
Copyright © 2011-2022 走看看