本篇介绍如何用sql tuning advisor来创建sql profile对sql进行调优。
(一) Sql tuning advisor
Sql tuning advisor可以在enterprise manager图形界面中调用,也可通过过程包调用。使用方法见后面的例子。
以下内容可以作为sql tuning advisor的输入,调优其中的问题sql:
l Addm (每小时自动运行)
l Awr
l Shared sql area
l Sql tuning set
调用sql tuning advisor时,优化器进入调优模式。
Oracle优化器有两种模式:
l Normal mode
快速产生对大多数sql来说合理的计划。要求生成计划的时间非常短
l Tuning mode
进行额外分析,如sql结构分析、sql profile、访问路径分析、替代写法等等,给出优化建议。通常调优一句sql需要几分钟,下面减少其中的sql profile。
(二) Sql profile是什么
Sql profile不是执行计划,而是提供以下信息帮助优化器选择plan
l 环境:db配置,绑定变量值,optimizer statistics,data set
l Supplemental statistics
因此可以说sql profile之于sql,相当于optimizer statistics之于table/index。
Sql profile的优点是:
l 与hints不同,使用sql profile不需改源程序。这点和outline一样
l 与hint和stored outline不同,profile通常不会固定执行计划,而是纠正优化器不正确的估计,因此在不同环境下更有弹性
Sql profile用来优化sql。当然使用了sql profile之后,也会达到稳定执行计划的目的。
(三) 应用举例
1. 准备
create table t1 as select * from dba_objects;
create table t2 as select * from dba_tables;
create index t1_idx on t1(object_name);
exec DBMS_STATS.GATHER_TABLE_STATS (ownname => 'LUW',tabname =>'t1',estimate_percent => 5,degree => 4,cascade => TRUE);
exec DBMS_STATS.GATHER_TABLE_STATS (ownname => 'LUW',tabname =>'t2',estimate_percent => 5,degree => 4,cascade => TRUE);
set autotrace traceonly
select t1.*,t2.owner from t1,t2 where t2.table_name like '%TO%' and t1.object_name=t2.table_name;
Plan hash value: 282751716
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 24 | 3000 | 350 (1)| 00:00:05 |
|* 1 | HASH JOIN | | 24 | 3000 | 350 (1)| 00:00:05 |
|* 2 | TABLE ACCESS FULL| T2 | 192 | 5184 | 42 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| T1 | 3734 | 357K| 307 (1)| 00:00:04 |
显示两张table全表扫描
2. 优化目标
目标是通过优化,使sql使用索引t1_idx,关联模式由hash join改为nest loop。
我们以前介绍过如何通过hint来修改执行计划。这里我们看看如何通过sql profile来达到同一目的。
3. 调用sql tuning advisor
在v$sql中找到上面那句sql的sql_id为8ug5kpjdjngp3
var tuning_task varchar2(100);
DECLARE
l_sql_id v$session.prev_sql_id%TYPE;
l_tuning_task VARCHAR2(30);
BEGIN
l_sql_id:='8ug5kpjdjngp3';
l_tuning_task := dbms_sqltune.create_tuning_task(sql_id => l_sql_id);
:tuning_task:=l_tuning_task;
dbms_sqltune.execute_tuning_task(l_tuning_task);
dbms_output.put_line(l_tuning_task);
END;
/
TASK_8723
4. 输出sql tuning advisor报告
set pagesize 0 long 30000000 longchunksize 2000
SELECT dbms_sqltune.report_tuning_task(:tuning_task) FROM dual;
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : TASK_8723
Tuning Task Owner : LUW
Workload Type : Single SQL Statement
Scope : COMPREHENSIVE
Time Limit(seconds): 1800
Completion Status : COMPLETED
Started at : 04/01/2013 16:47:31
Completed at : 04/01/2013 16:47:32
-------------------------------------------------------------------------------
Schema Name: LUW
SQL ID : 8ug5kpjdjngp3
SQL Text : select t1.*,t2.owner from t1,t2 where t2.table_name like '%TO%'
and t1.object_name=t2.table_name
-------------------------------------------------------------------------------
FINDINGS SECTION (2 findings)
-------------------------------------------------------------------------------
1- SQL Profile Finding (see explain plans section below)
--------------------------------------------------------
A potentially better execution plan was found for this statement.
Recommendation (estimated benefit: 62.97%)
------------------------------------------
- Consider accepting the recommended SQL profile.
execute dbms_sqltune.accept_sql_profile(task_name => 'TASK_8723',
task_owner => 'LUW', replace => TRUE);
Validation results
------------------
The SQL profile was tested by executing both its plan and the original plan
and measuring their respective execution statistics. A plan may have been
only partially executed if the other could be run to completion in less time.
Original Plan With SQL Profile % Improved
------------- ---------------- ----------
Completion Status: COMPLETE COMPLETE
Elapsed Time (s): .067587 .004296 93.64 %
CPU Time (s): .068 .004 94.11 %
User I/O Time (s): 0 0
Buffer Gets: 1234 459 62.8 %
Physical Read Requests: 0 0
Physical Write Requests: 0 0
Physical Read Bytes: 0 0
Physical Write Bytes: 0 0
Rows Processed: 171 171
Fetches: 171 171
Executions: 1 1
Notes
-----
1. Statistics for the original plan were averaged over 10 executions.
2. Statistics for the SQL profile plan were averaged over 10 executions.
2- Restructure SQL finding (see plan 1 in explain plans section)
----------------------------------------------------------------
The predicate "T1"."OBJECT_NAME" LIKE '%TO%' used at line ID 3 of the
execution plan contains an expression on indexed column "OBJECT_NAME". This
expression prevents the optimizer from selecting indices on table "LUW"."T1".
Recommendation
--------------
- Rewrite the predicate into an equivalent form to take advantage of
indices. Alternatively, create a function-based index on the expression.
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
1- Original With Adjusted Cost
------------------------------
Plan hash value: 282751716
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 179 | 22375 | 350 (1)| 00:00:05 |
|* 1 | HASH JOIN | | 179 | 22375 | 350 (1)| 00:00:05 |
|* 2 | TABLE ACCESS FULL| T2 | 192 | 5184 | 42 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| T1 | 1016 | 99568 | 307 (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."OBJECT_NAME"="T2"."TABLE_NAME")
2 - filter("T2"."TABLE_NAME" LIKE '%TO%')
3 - filter("T1"."OBJECT_NAME" LIKE '%TO%' AND "T1"."OBJECT_NAME" IS
NOT NULL)
2- Using SQL Profile
--------------------
Plan hash value: 2963590314
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 13 | 1716 | 26 |
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 13 | 1274 | 3 |
| 2 | NESTED LOOPS | | 13 | 1716 | 26 |
|* 3 | TABLE ACCESS FULL | T2 | 1 | 34 | 23 |
|* 4 | INDEX RANGE SCAN | T1_IDX | 1 | | 2 |
----------------------------------------------------------------------
上述报告亮色字体部分,显示tuning advisor找到了sql profile,以及采用该profile的command。并显示当前的执行计划和cost(为350);采用profile后的执行计划和cost(为26),通过cost对比说明采用profile性能是能提升的。
5. 根据advisor
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/18474/viewspace-1060806/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/18474/viewspace-1060806/