SQL Profiles使用实例

SQL Profiles使用实例

在统计信息不完整或者缺失时,有时优化器会产生错误的判断,产生性能比较低下的执行计划。传统的方式,通过手工添加相关的提示生成正确的执行计划。但对于那些封装好的应用程序,修改代码不是一件容易的事情,相信这个问题也曾经困扰过很多的DBA。在Oracle10g中可以很方便的使用自动SQL调整(Automatic SQL Tuning)来调整这些SQL语句,而不用去修改应用代码。其中使用的关键技术就是强大的SQL Profiles。

下面通过一个小例子,看看SQL Profiles是如何进行SQL语句自动调整的。

1. 使用HR用户登录,创建测试用例

SQL> create table test (n number );

Table created.

SQL> begin
for i in 1 .. 10000 loop
insert into test values(i);
commit;
end loop;
end;
/

PL/SQL procedure successfully completed.

2. 创建索引并进行分析

SQL> create index test_idx on test(n);

Index created.

SQL> analyze table test estimate statistics;

Table analyzed.

3. 执行SQL语句,模拟一个性能低下的执行计划

SQL> select /*+ no_index(test test_idx) */ * from hr.test where n=1;

Execution Plan
———————————————————-
Plan hash value: 1357081020

————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
————————————————————————–
| 0 | SELECT STATEMENT | | 1 | 3 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| TEST | 1 | 3 | 6 (0)| 00:00:01 |
————————————————————————–

4. 使用SYS用户登录,创建自动调整任务

DECLARE
my_task_name VARCHAR2(30);
my_sqltext CLOB;
BEGIN
my_sqltext := ’select /*+ no_index(test test_idx) */ * from hr.test where n=1′;
my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_text => my_sqltext,
user_name => ‘SCOTT’,
scope => ‘COMPREHENSIVE’,
time_limit => 60,
task_name => ‘tuning_task_1′,
description => ‘Task to tune a query on a specified table’);
END;
/

PL/SQL procedure successfully completed.

5. 执行自动调整任务并输出结果

SQL> exec DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => ‘tuning_task_1′);

PL/SQL procedure successfully completed.

SQL> SET LONG 1000
SQL> SET LONGCHUNKSIZE 1000
SQL> SET LINESIZE 100
SQL> SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( ‘tuning_task_1′) from DUAL;

DBMS_SQLTUNE.REPORT_TUNING_TASK(‘TUNING_TASK_1′)
——————————————————————————-
GENERAL INFORMATION SECTION
——————————————————————————-
Tuning Task Name : tuning_task_1
Tuning Task Owner : SYS
Scope : COMPREHENSIVE
Time Limit(seconds) : 60
Completion Status : COMPLETED
Started at : 07/02/2010 15:48:07
Completed at : 07/02/2010 15:48:08
Number of SQL Profile Findings : 1

——————————————————————————-
Schema Name: SCOTT
SQL ID : 8m2dnmd4a7vx0
SQL Text : select /*+ no_index(test test_idx) */ * from hr.test where n=1

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

1- SQL Profile Finding (see explain plans section below)
——————————————————–
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 => ‘tuning_task_1′,
replace => TRUE);

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

1- Original With Adjusted Cost
——————————
Plan hash value: 1357081020

————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
————————————————————————–
| 0 | SELECT STATEMENT | | 1 | 3 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| TEST | 1 | 3 | 6 (0)| 00:00:01 |
————————————————————————–

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

1 – filter(“N”=1)

2- Using SQL Profile
——————–
Plan hash value: 2882402178

—————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
—————————————————————————–
| 0 | SELECT STATEMENT | | 1 | 3 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| TEST_IDX | 1 | 3 | 1 (0)| 00:00:01 |
—————————————————————————–

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

1 – access(“N”=1)

——————————————————————————-

从上面的输出可以看出,自动调整任务发现了一个更好的执行计划,并推荐使用这个计划。

6. 接受执行计划

DECLARE
my_sqlprofile_name VARCHAR2(30);
BEGIN
my_sqlprofile_name := DBMS_SQLTUNE.ACCEPT_SQL_PROFILE (
task_name => ‘tuning_task_1′,
name => ‘my_sql_profile’);
END;
/

PL/SQL procedure successfully completed.

SQL> select to_char(sql_text) from dba_sql_profiles;

TO_CHAR(SQL_TEXT)
————————————————————————
select /*+ no_index(test test_idx) */ * from hr.test where n=1

7. 再次执行相同的语句,验证结果

SQL> select /*+ no_index(test test_idx) */ * from hr.test where n=1;

Execution Plan
———————————————————-
Plan hash value: 2882402178

—————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
—————————————————————————–
| 0 | SELECT STATEMENT | | 1 | 3 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| TEST_IDX | 1 | 3 | 1 (0)| 00:00:01 |
—————————————————————————–

这里可以看出,Oracle已经使用了不同的执行计划。

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/16298743/viewspace-1045829/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/16298743/viewspace-1045829/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值