zoukankan      html  css  js  c++  java
  • 使用SQL Profile及SQL Tuning Advisor固定运行计划

    SQL Profile就是为某一SQL语句提供除了系统统计信息、对象(表和索引等)统计信息之外的其它信息,比方执行环境、额外的更准确的统计信息,以帮助优化器为SQL语句选择更适合的执行计划。
    SQL Profiles可以说是Outlines的进化。Outlines可以实现的功能SQL Profiles也全然可以实现,而SQL Profiles具有Outlines不具备的优化,最重要的有二点:
        SQL Profiles更easy生成、更改和控制。


        SQL Profiles在对SQL语句的支持上做得更好。也就是适用范围更广。


    使用SQL Profiles两个目的:
        锁定或者说是稳定运行计划。


        在不能改动应用中的SQL的情况下使SQL语句按指定的执行计划执行。
    參考老熊的博客。链接:http://www.laoxiong.net/sql-profiles-partii.html    http://www.laoxiong.net/sql-profiles-part.html   http://blog.sina.com.cn/s/blog_5037eacb01011mgu.htm

    1.实验环境构造语句:

    create table bys.t1 as select * from dba_objects;
    create index bys.t1_idx on t1(object_id);
    exec dbms_stats.gather_table_stats('bys','t1',cascade=>true,degree=>4);
    set autotrace trace;
    select a.*,b.owner from t1 a,t1 b where a.object_name like '%T1%' and a.object_id=b.object_id;
    select /*+ use_nl(a b) index(t2) */ a.*,b.owner from t1 a,t1 b where a.object_name like '%T1%' and a.object_id=b.object_id;
    set autotrace off;
    explain plan for select /*+ use_nl(a b) index(t2) */ a.*,b.owner from t1 a,t1 b where a.object_name like '%T1%' and a.object_id=b.object_id;
    col sql_text for a100
    SELECT SQL_ID,SQL_TEXT FROM V$SQL WHERE SQL_TEXT LIKE '%a.*,b.owner from t1 a,t1 b%';
    ####2t5xqt4d1dsaw
    10g開始,v$sql_plan中就包含了SQL语句OUTLINE数据,也就是稳定运行计划的Hints。例如以下:
    set pagesize 1000
    SQL> select * from table(dbms_xplan.display_cursor('2t5xqt4d1dsaw',null,'outline'));
    PLAN_TABLE_OUTPUT
    ---------------------------------------------------------------------------------------------------------------
    SQL_ID  2t5xqt4d1dsaw, child number 0
    -------------------------------------
    select /*+ use_nl(a b) index(t2) */ a.*,b.owner from t1 a,t1 b where
    a.object_name like '%T1%' and a.object_id=b.object_id
    Plan hash value: 190596302
    --------------------------------------------------------------------------------------
    | Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |        |       |       |   979 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1     |     1 |     9 |     2   (0)| 00:00:01 |
    |   2 |   NESTED LOOPS              |        |   471 | 43803 |   979   (1)| 00:00:12 |
    |*  3 |    TABLE ACCESS FULL        | T1     |   471 | 39564 |    36   (0)| 00:00:01 |
    |*  4 |    INDEX RANGE SCAN         | T1_IDX |     1 |       |     1   (0)| 00:00:01 |
    --------------------------------------------------------------------------------------

    Outline Data              ----------这一部分: /*+     */ 之间的就是所需的数据了
    -------------
      /*+
          BEGIN_OUTLINE_DATA
          IGNORE_OPTIM_EMBEDDED_HINTS
          OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
          ALL_ROWS
          OUTLINE_LEAF(@"SEL$1")
          FULL(@"SEL$1" "A"@"SEL$1")
          INDEX(@"SEL$1" "B"@"SEL$1" ("T1"."OBJECT_ID"))
          LEADING(@"SEL$1" "A"@"SEL$1" "B"@"SEL$1")
          USE_NL(@"SEL$1" "B"@"SEL$1")
          END_OUTLINE_DATA
      */


    PLAN_TABLE_OUTPUT
    -----------------------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       3 - filter("A"."OBJECT_NAME" LIKE '%T1%')
       4 - access("A"."OBJECT_ID"="B"."OBJECT_ID")
    ###############################################################################

    2.開始创建并应用SQL Profile

    使用未加HINT的SQL语句,并指定SQL_PROFILE名字:SQLPROFILE_T1
    注意事项:两个引號---如('10.2.0.1')要写成(''10.2.0.1'')--'%T1%'写成''%T1%''
    SQL语句结尾的;不要写上,绑定变量值是'1'时,要输入''1''
     declare
     v_hints sys.sqlprof_attr;
     begin
     v_hints:=sys.sqlprof_attr(
          'BEGIN_OUTLINE_DATA',
          'IGNORE_OPTIM_EMBEDDED_HINTS',
          'OPTIMIZER_FEATURES_ENABLE(''10.2.0.1'')',
          'ALL_ROWS',
          'OUTLINE_LEAF(@"SEL$1")',
          'FULL(@"SEL$1" "A"@"SEL$1")',
          'INDEX(@"SEL$1" "B"@"SEL$1" ("T1"."OBJECT_ID"))',
          'LEADING(@"SEL$1" "A"@"SEL$1" "B"@"SEL$1")',
          'USE_NL(@"SEL$1" "B"@"SEL$1")',
          'END_OUTLINE_DATA');
    dbms_sqltune.import_sql_profile(
    'select a.*,b.owner from t1 a,t1 b where a.object_name like ''%T1%'' and a.object_id=b.object_id',
    v_hints,'SQLPROFILE_T1',                
    force_match=>true,replace=>true);
    end;
    /
    删除语句:
    exec dbms_sqltune.drop_sql_profile(name =>'SQLPROFILE_T1' );
    ######

    3.验证SQL语句是否使用上一步创建的SQL_PROFILE:

    SQL> set autotrace trace;
    SQL> select a.*,b.owner from t1 a,t1 b where a.object_name like '%T1%' and a.object_id=b.object_id;
    23 rows selected.
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 190596302
    --------------------------------------------------------------------------------------
    | Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |        |   471 | 43803 |   979   (1)| 00:00:12 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1     |     1 |     9 |     2   (0)| 00:00:01 |
    |   2 |   NESTED LOOPS              |        |   471 | 43803 |   979   (1)| 00:00:12 |
    |*  3 |    TABLE ACCESS FULL        | T1     |   471 | 39564 |    36   (0)| 00:00:01 |
    |*  4 |    INDEX RANGE SCAN         | T1_IDX |     1 |       |     1   (0)| 00:00:01 |
    --------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       3 - filter("A"."OBJECT_NAME" LIKE '%T1%')
       4 - access("A"."OBJECT_ID"="B"."OBJECT_ID")
    Note
    -----
       - SQL profile "SQLPROFILE_T1" used for this statement

    Statistics
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
            163  consistent gets
              0  physical reads
              0  redo size
           2609  bytes sent via SQL*Net to client
            392  bytes received via SQL*Net from client
              3  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             23  rows processed          0  sorts (disk)
    #####################################################################      

    使用Oracle的SQL Tuning Advisor固定运行计划--SQL_ID

    ----通过sql_id的方式  sql_id => 'a2h6pzvqncfvg',--想调优的sql_id

    show serveroutput
    set serveroutput on;

    DECLARE  
        a_tuning_task VARCHAR2(30);  
      BEGIN  
        a_tuning_task := dbms_sqltune.create_tuning_task(sql_id => 'a2h6pzvqncfvg',task_name => 'tuning_test');    
        dbms_sqltune.execute_tuning_task(a_tuning_task);   
      END;  
      /
    set long 1000
    SELECT dbms_sqltune.report_tuning_task('tuning_test') FROM dual;
     
    这里的输出中的sql_id是从v$sql查出。相应的是没有加hint的SQL。
    假设SQL Tuning Advisor找到了理想的运行计划。下一步就是:Accept SQL Profile,接受这个SQL Profile。

    ## execute dbms_sqltune.accept_sql_profile(task_name =>'tuning_test' ,replace => TRUE,force_match=>true);
     完毕后验证语句
    set autotrace trace;
    select a.*,b.owner from t1 a,t1 b where a.object_name like '%T1%' and a.object_id=b.object_id;
    set autotrace off;
    删除SQL语句:
    exec dbms_sqltune.drop_tuning_task('tuning_test');  
     假设未找到理想的运行计划,则參考下一个方法。
    ##################################################################

    使用Oracle的SQL Tuning Advisor固定运行计划--使用SQL_TEXT,參考下面:

    DECLARE
     my_task_name VARCHAR2 (30);
     my_sqltext CLOB;
     BEGIN
     my_sqltext := 'select * from test where OBJECT_ID=15';  --想调优的sql
     my_task_name := dbms_sqltune.create_tuning_task (sql_text=> my_sqltext,
     --bind_list =>  'UNDO$',
     --user_name => 'SONG',
     --scope => 'COMPREHENSIVE',
     --time_limit => 60,
     task_name => 'sql_tuning_test'
     --description => 'Tuning Task'
     );
     END;
     /
     
     exec dbms_sqltune.execute_tuning_task('sql_tuning_test');   --运行调优的任务
      SELECT STATUS FROM USER_ADVISOR_TASKS WHERE task_name = 'sql_tuning_test'; --查看调优作业的状态
     SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('sql_tuning_test') FROM DUAL;--查看调优的建议
     exec dbms_sqltune.drop_tuning_task('sql_tuning_test');--删除任务

  • 相关阅读:
    最大子序列和问题的几种算法
    给Repeater控件里添加序号的5种方法
    关于上传(上传所用到的upload和upload的应用)
    .net中的动态时钟 (年月日 时分秒)
    网页总结
    PHP算法将数字金额转换成大写金额
    Linux下编译安装redis,详细教程
    如何让PHP支持Redis
    网络互连技术——第一章随记
    网络互连技术——第二章考试需知
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/7120084.html
Copyright © 2011-2022 走看看