1、创建优化任务并执行
使用SQL Profile还必须有CREATE ANY SQL PROFILE、DROP ANY SQL PROFILE和ALTER ANY SQL PROFILE等系统权限
set timing off
DECLARE
my_task_name VARCHAR2(30);
my_sqltext CLOB;
BEGIN
my_sqltext := 'select count(*) from bigtab a, smalltab b where a.object_name=b.table_name';
my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_text => my_sqltext,
user_name => 'DEMO',
scope => 'COMPREHENSIVE',
time_limit => 60,
task_name => 'tuning_sql_test',
description => 'Task to tune a query on a specified table');
DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => 'tuning_sql_test');
END;
/
也可以使用sql_id
var tuning_task varchar2(100);
DECLARE
l_sql_id v$session.prev_sql_id%TYPE;
l_tuning_task VARCHAR2(30);
BEGIN
l_sql_id:='4zbqykx89yc8v';
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;
/
select task_name, status from USER_ADVISOR_LOG where task_name='tuning_%';
--可以通过视图USER_ADVISOR_LOG查看优化任务。
2、查看优化结果
set long 10000
set longchunksize 1000
set linesize 100
print tuning_task
SELECT dbms_sqltune.report_tuning_task(:tuning_task) FROM dual;
3、按照优化建议进行优化
execute dbms_sqltune.accept_sql_profile(task_name => 'TASK_241',task_owner => 'YALI', replace => TRUE,force_match => TRUE);
Description是profile的描述信息;task_owner是优化建议任务的所有者;replace为TRUE时,如果这个profile已经存在,就代替它;force_match为TURE时表示与语句强制匹配,即强制使用绑定变量,和系统参数cursor_sharing设置为FORCE时类似,为FALSE时,与cursor_sharing设置为EXACT时类似,即完全匹配。
这里要特别提到的是category这个参数,你可以通过设置这个参数,制定特定会话使用这个profile。在10g中,每个会话都有一个新参数SQLTUNE_CATEGORY,他的默认值是DEFAULT。而我们在调用这个函数时,如果没有指定这个参数,那它的值也是DEFAULT,而如果我们给这个profile指定了一个其它的CATEGORY值,如FOR_TUNING,那么只有会话参数SQLTUNE_CATEGORY也为FOR_TUNING时,才会使用这个porfile。为什么说这个参数很有用呢?试想一个这样的环境:你在一个生产系统上利用STA调优一条语句,STA已经给出了优化建议,但是你又不敢贸然实施它给出的建议(毕竟它只是机器嘛,不能完全信任),你就可以创建一个有特殊CATEGORY的profile,然后在你自己的会话中制定SQLTUNE_CATEGORY为这个特殊的CATEGORY,那就既可以看优化建议的实际效果又不影响生产环境。
4、控制sql profile
exec DBMS_SQLTUNE.ALTER_SQL_PROFILE(name => 'my_sql_profile',attribute_name => 'STATUS', value => 'DISABLED'); --失效
exec DBMS_SQLTUNE.DROP_SQL_PROFILE(name => 'my_sql_profile'); --删除
5、profile的转储与移植
DBMS_SQLTUNE包提供了另外几个函数用于将profile的数据导出到表中,然后可以再将表中的数据移植到其它环境中
1}、创建存储表
begin
DBMS_SQLTUNE.CREATE_STGTAB_SQLPROF (
table_name => 'PROFILE_STGTAB',
schema_name => 'DEMO',
tablespace_name => 'EDGARDEMO');
end;
/
2)、将profile中数据存入存储表中
BEGIN
DBMS_SQLTUNE.PACK_STGTAB_SQLPROF (
profile_name => '%',
profile_category => 'DEFAULT',
staging_table_name => 'PROFILE_STGTAB',
staging_schema_owner => 'DEMO');
END;
/
另外,可以通过存储过程来修改存储表中的信息:
begin
DBMS_SQLTUNE.REMAP_STGTAB_SQLPROF (
old_profile_name => 'my_sql_profile',
new_profile_name => 'new_sql_profile',
new_profile_category => 'DEV',
staging_table_name => 'PROFILE_STGTAB',
staging_schema_owner => 'DEMO');
end;
/
3)、从存储表中导入profile数据
create table STGTAB as select * from PROFILE_STGTAB@EDGAR;
然后将数据导出为profile
begin
DBMS_SQLTUNE.UNPACK_STGTAB_SQLPROF (
profile_name => 'new_sql_profile',
profile_category => 'DEV',
replace => FALSE,
staging_table_name => 'STGTAB',
staging_schema_owner => 'DEMO');
end;
/
select name, category, sql_text from DBA_SQL_PROFILES; ---查看导入情况