Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6666919
  • 博文数量: 1005
  • 博客积分: 8199
  • 博客等级: 中将
  • 技术积分: 13071
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-25 20:19
个人简介

脚踏实地、勇往直前!

文章分类

全部博文(1005)

文章存档

2020年(2)

2019年(93)

2018年(208)

2017年(81)

2016年(49)

2015年(50)

2014年(170)

2013年(52)

2012年(177)

2011年(93)

2010年(30)

分类: Oracle

2012-06-02 23:31:39

环境:
OS:Red Hat Linux As 5
DB:10.2.0.4
 
Oracle通过STA给出某个SQL执行建议,下面通过一个测试检查Oracle给出的优化建议是否正确.
 
1.建表并生成测试数据
SQL> create table tb_test(id number not null,name varchar2(30));
Table created.
SQL> create index idx_tb_test on tb_test(id);
Index created.
SQL> declare
begin
  for i in 1 .. 100000 loop
    insert into tb_test values (i, 'test');
    commit;
  end loop;
end;
/
 
2.分析表
begin
  dbms_stats.gather_table_stats(ownname => 'SCOTT', tabname => 'TB_TEST');
end;

3.编造一个执行计划不对的SQL

select/*+ full(t)*/ count(1) from scott.tb_test t where t.id=1

我们知道在ID列上有索引,这个SQL走索引是正确的执行计划,但这里强制oracle走全表扫描,然后通过STA,看oracle给出的执行计划是否正确.

4.创建TUNING_TASK并执行

declare
  l_task_name varchar2(30);
  l_sql       clob;
begin
  l_sql       := 'select/*+ full(t)*/ count(1) from scott.tb_test t where t.id=1';
  l_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_text    => l_sql,
                                                 user_name   => 'SCOTT',
                                                 scope       => 'COMPREHENSIVE',
                                                 time_limit  => 60,
                                                 task_name   => 'task_name01',
                                                 description => null);
dbms_sqltune.Execute_tuning_task(task_name => 'task_name01');
end;

5.查看oracle给出的优化建议

SQL> set serveroutput on;
SQL> set long 999999999;
SQL> SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('task_name01') FROM DUAL;

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_NAME01')
--------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name                  : task_name01
Tuning Task Owner                 : SYS
Scope                             : COMPREHENSIVE
Time Limit(seconds)               : 60
Completion Status                 : COMPLETED
Started at                        : 06/03/2012 00:07:58
Completed at                      : 06/03/2012 00:07:59
Number of SQL Profile Findings    : 1


DBMS_SQLTUNE.REPORT_TUNING_TASK('MY_TASK_NAME01')
--------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Schema Name: SCOTT
SQL ID     : ga3q5tqjgsj5u
SQL Text   : select/*+ full(t)*/ count(1) from scott.tb_test t where t.id=1

-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------

1- SQL Profile Finding (see explain plans section below)
--------------------------------------------------------

DBMS_SQLTUNE.REPORT_TUNING_TASK('MY_TASK_NAME01')
--------------------------------------------------------------------------------
  A potentially better execution plan was found for this statement.

  Recommendation (estimated benefit: 84.11%)
  ------------------------------------------
  - Consider accepting the recommended SQL profile.
    execute dbms_sqltune.accept_sql_profile(task_name => 'task_name01',
            replace => TRUE);

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_NAME01')
--------------------------------------------------------------------------------

1- Original With Adjusted Cost
------------------------------
Plan hash value: 1372292586

--------------------------------------------------------------------------------

| Id  | Operation          | Name      | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------

-- 当前的执行计划
DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_NAME01')
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |           |     1 |     4 |     6   (0)| 00:00:01 |

|   1 |  SORT AGGREGATE    |           |     1 |     4 |            |          |

|*  2 |   TABLE ACCESS FULL| TB_TEST   |     1 |     4 |     6   (0)| 00:00:01 |

--------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_NAME01')
--------------------------------------------------------------------------------

   2 - filter("T"."ID"=1)

 

-- Oracle给出的执行计划

2- Using SQL Profile
--------------------
Plan hash value: 847665939

--------------------------------------------------------------------------------
---
| Id  | Operation         | Name          | Rows  | Bytes | Cost (%CPU)| Time
  |

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_NAME01')
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
---
|   0 | SELECT STATEMENT  |               |     1 |     4 |     1   (0)| 00:00:0
1 |
|   1 |  SORT AGGREGATE   |               |     1 |     4 |            |
  |
|*  2 |   INDEX RANGE SCAN| IDX_TB_TEST   |     1 |     4 |     1   (0)| 00:00:0
1 |
--------------------------------------------------------------------------------
---


DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_NAME01')
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("T"."ID"=1)

-------------------------------------------------------------------------------

从上面的输出可以看出Oracle给出的执行计划是正确的.可以使用如下方法使用正确的执行计划

begin
  dbms_sqltune.accept_sql_profile(task_name => 'task_name01', replace => TRUE);
end;

-- The End --

 



阅读(3687) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~