DBMS_SQLTUNE优化SQL 是在oracle10g才出来的新特性,使用它能很大程度上方便对sql的分析和优化。执行DBMS_SQLTUNE包进行sql优化需要有advisor的权限:
grant advisor to user;
使用DBMS_SQLTUNE包进行SQL优化,大致可以分为四个步骤:
创建优化任务
执行优化任务
显示优化任务的结果
按照建议执行优化
以下以sys用户为例,使用SQL Profile过程: 以下程序摘自(Oracle DBA手记2 page94-98)
1.创建测试表及索引
SQL> create table big_table_prof as select rownum
2 as id, t.* from all_objects t;
表已创建。
SQL> create index idx_big_table_prof on big_table_prof(id);
索引已创建。
2.查看执行计划
2.1 分析表big_table_prof
SQL> exec dbms_stats.gather_table_stats(user,'big_table_prof');
PL/SQL 过程已成功完成。
SQL> set linesize 100
SQL> set autotrace traceonly exp
2.2 访问索引SQL
SQL> select count(*) from big_table_prof where id<100;
执行计划
----------------------------------------------------------
Plan hash value: 47754723
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 2 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | INDEX RANGE SCAN| IDX_BIG_TABLE_PROF | 62 | 310 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"<100)
2.3 强行加入full hints使其变为全表扫描:
SQL> select /*+full(t)*/ count(*) from big_table_prof t where id < 100;
执行计划
----------------------------------------------------------
Plan hash value: 3149272518
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 186 (2)| 00:00:03 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | TABLE ACCESS FULL| BIG_TABLE_PROF | 62 | 310 | 186 (2)| 00:00:03 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("ID"<100)
3.调用dbms_sqltune调优建议者以创建调优任务,并报告执行结果
1 declare
2 v_task_name varchar2(40);
3 begin
4 v_task_name := dbms_sqltune.create_tuning_task
5 (sql_text=>'select /*+full(t)*/ count(*) from big_table_prof t where id<100',
6 task_name=>'task_big_table_prof');
7 dbms_sqltune.execute_tuning_task(v_task_name);
8 dbms_output.put_line(v_task_name);
9* end;
SQL> /
PL/SQL 过程已成功完成。
4.SQL> select status from user_advisor_tasks where task_name='first_tuning_task13';
STATUS
-----------
COMPLETED
5. 显示优化任务的结果
SQL> set serveroutput on size 100000
SQL> set long 100000
SQL> select dbms_sqltune.report_tuning_task('task_big_table_prof') from dual;
DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_BIG_TABLE_PROF')
--------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : task_big_table_prof 调优任务名
Tuning Task Owner : SYS 所有者
Scope : COMPREHENSIVE
Time Limit(seconds) : 1800
Completion Status : COMPLETED
Started at : 06/30/2012 17:37:31
Completed at : 06/30/2012 17:37:31
Number of SQL Profile Findings : 1
DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_BIG_TABLE_PROF')
--------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Schema Name: SYS
SQL ID : 65mnw6588hyjg
SQL Text : select /*+full(t)*/ count(*) from big_table_prof t where id<100
-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------
1- SQL Profile Finding (see explain plans section below)
--------------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_BIG_TABLE_PROF')
--------------------------------------------------------------------------------
为此语句找到了性能
Recommendation (estimated benefit: 98.92%)
------------------------------------------
-考虑接受推荐的 SQL
execute dbms_sqltune.accept_sql_profile(task_name =>
'task_big_table_prof', replace => TRUE);
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_BIG_TABLE_PROF')
--------------------------------------------------------------------------------
1- Original With Adjusted Cost
------------------------------
Plan hash value: 3149272518
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 186 (2)| 00:00
3 |
| 1 | SORT AGGREGATE | | 1 | 5 | |
DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_BIG_TABLE_PROF')
--------------------------------------------------------------------------------
|* 2 | TABLE ACCESS FULL| BIG_TABLE_PROF | 62 | 310 | 186 (2)| 00:00
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("ID"<100)
2- Using SQL Profile
--------------------
Plan hash value: 47754723
DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_BIG_TABLE_PROF')
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Ti
|
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 2 (0)| 00
| 1 | SORT AGGREGATE | | 1 | 5 | |
|* 2 | INDEX RANGE SCAN| IDX_BIG_TABLE_PROF | 62 | 310 | 2 (0)| 00
--------------------------------------------------------------------------------
------
DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_BIG_TABLE_PROF')
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"<100)
-------------------------------------------------------------------------------
6.按照建议执行优化
SQL> set linesize 100
SQL> select /*+full(t)*/ count(*) from big_table_prof t where id < 100;
COUNT(*)
----------
99
执行计划
----------------------------------------------------------
Plan hash value: 47754723
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 2 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | INDEX RANGE SCAN| IDX_BIG_TABLE_PROF | 62 | 310 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"<100)
Note
-----
- SQL profile "SYS_SQLPROF_014e0f6d696a4000" used for this statement [此处注明此SQL语句使用了SQL profile优化].
由此可知,当我们无法改变应用程序的SQL语句时,可以利用SQL Profiles来影响执行计划。
Made by DylanX.