PLSQL_性能优化工具系列08_SQL Access Advisor

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

你可能感兴趣的:(Access)