2015-01-22 Created By BaoXinjian
一、摘要
SQL访问顾问(SQL Access Advisor)介绍
SQL Access Advisor是Oracle顾问框架的一个组件,可以帮助人们确定那些索引、物理化视图等对提高单个查询、整个工作或者指定方案性能。
SQL Access Advisor为数据仓库或者决策支持环境等主要操作是SELECT的场合带来最大效益。
1. SQL Access Advisor执行的分析包括以下几种
(1). 考虑只有索引、只有物理化视图还是二者都有能够获得最大的效益。
(2). 在推荐生成新索引或者物理化视图时,在存储、维护方面的开销与性能提高之间进行平衡。
(3). 如果指定的是全部负荷(full workload),那么生成DROP推荐意见来删除未用的索引或物理化视图。
(4). 优化物理化视图,在可能的情况下实现快速刷新
(5). 推荐物理化视图日志以便快速刷新
(6). 推荐在适合的场所降多个索引组合成一个索引
2. SQL Access Advisor执行的过程
Step1.创建一个任务
在作出任何建议之间,必须创建一个任务。
这个任务很重要,因为它保存了关于建议程 序的所有信息,包括建议程序的结果。
如果你使用Oracle企业管理器的向导或DBMS_ADVISOR.QUICK_TUNE过程,任务会自动创建。其 他情况,你必须使用DBMS_ADVISOR.CREATE_TASK过程来创建一个任务。
你可以用DBMS_ADVISOR.SET_TASK_PARAMETER过程来定义参数,从而控制任务要做什么。
Step2. 定义工作量(workload)
工作量是调用SQL访问顾问的主要输入之一,它由一个或多个SQL语句构成,加上完全描述每个语句的各种统计信息和属性。
如果工作量包含了一个目标商业应用的所有SQL语句,那么这个工作量被认为是一个全工作量;
如果工作量包含所有SQL语句的一个子集,那么它就被认为是部分工作量。
全工作量和部分工作量之间的不同是全工作量下,如果SQL访问顾问发现已存在的物化视图和索引并没有有效地使用,那么它会建议删除它们。
Step3. 典型地SQL访问顾问使用工作量作为所有分析的基础
尽管工作量包含非常广泛的语句,它还是仔细地根据特定统计信息,业务重要性,或统计信息和业 务重要性的组合进行分等级。
这个等级是很关键的,它可以使SQL访问顾问先处理最重要的SQL语句,然后是那些业务影响更小的语句。
3. 结构图
二、案例
案例: 创建一个表,未走索引,是全表扫描,查看Oracle SQL Access Advisor是否有正确意见 - 创建表索引
1.建表并生成测试数据
SQL> connect scott/scott Connected. SQL> drop table tb_test; 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.分析表
connect / as sysdba begin dbms_stats.gather_table_stats(ownname => 'SCOTT', tabname => 'TB_TEST',cascade => true); end;
3.使用dbms_advisor.quick_tune生成优化建议
connect / as sysdba declare l_task_name VARCHAR2(255); l_sql_stmt VARCHAR2(4000); begin l_sql_stmt := 'select /*+ full(t) */ * from scott.tb_test t where t.id = :1'; l_task_name := 'MY_FULL_ACCESS_TEST'; DBMS_ADVISOR.QUICK_TUNE(DBMS_ADVISOR.SQLACCESS_ADVISOR, l_task_name, l_sql_stmt); exception when others then dbms_output.put_line(sqlerrm); end;
我们这里造一个走全表扫描的索引,很明显走索引才是正确的,这里的目的主要是看oracle会给出什么样的建议.
4.查看优化建议
SQL> set serveroutput on; SQL> set long 999999999; SQL> begin show_recm('MY_FULL_ACCESS_TEST'); end; ========================================= Task_name = MY_FULL_ACCESS_TEST Action ID: 1 Command : RETAIN INDEX Attr1 (name) : "SCOTT"."IDX_TB_TEST_N1" Attr2 (tablespace): Attr3 : "SCOTT"."TB_TEST" Attr4 : BTREE Attr5 : ----------------------------------------
=========END RECOMMENDATIONS============ PL/SQL procedure successfully completed.
从以上输出可以看出oracle给出的建议是走索引.
5. 客制化叫板呢show_recm
CREATE OR REPLACE PROCEDURE show_recm (in_task_name IN VARCHAR2) IS
CURSOR curs IS
SELECT DISTINCT action_id, command, attr1, attr2, attr3, attr4 FROM dba_advisor_actions WHERE task_name = in_task_name ORDER BY action_id; v_action number; v_command VARCHAR2(32); v_attr1 VARCHAR2(4000); v_attr2 VARCHAR2(4000); v_attr3 VARCHAR2(4000); v_attr4 VARCHAR2(4000); v_attr5 VARCHAR2(4000); BEGIN
OPEN curs; DBMS_OUTPUT.PUT_LINE('========================================='); DBMS_OUTPUT.PUT_LINE('Task_name = ' || in_task_name); LOOP FETCH curs INTO v_action, v_command, v_attr1, v_attr2, v_attr3, v_attr4 ; EXIT when curs%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Action ID: ' || v_action); DBMS_OUTPUT.PUT_LINE('Command : ' || v_command); DBMS_OUTPUT.PUT_LINE('Attr1 (name) : ' || SUBSTR(v_attr1,1,30)); DBMS_OUTPUT.PUT_LINE('Attr2 (tablespace): ' || SUBSTR(v_attr2,1,30)); DBMS_OUTPUT.PUT_LINE('Attr3 : ' || SUBSTR(v_attr3,1,30)); DBMS_OUTPUT.PUT_LINE('Attr4 : ' || v_attr4); DBMS_OUTPUT.PUT_LINE('Attr5 : ' || v_attr5); DBMS_OUTPUT.PUT_LINE('----------------------------------------'); END LOOP; CLOSE curs; DBMS_OUTPUT.PUT_LINE('=========END RECOMMENDATIONS============'); END show_recm;
Thanks and Regards
参考:Oracle - http://www.oracle.com/technetwork/cn/articles/11g-sqlaccessadvisor-093323-zhs.html