1. 程式人生 > >SQL訪問顧問SAA(SQL Access Advisor)理論部分十二:執行快速優化quick_tune

SQL訪問顧問SAA(SQL Access Advisor)理論部分十二:執行快速優化quick_tune

執行快速優化
如果只想要優化單個SQL語句,dbms_advisor.quick_tune過程將接受任務名與一個SQL語句作為引數 來執行。它將建立一個任務與工作量,並且執行任務。使用dbms_advisor.quick_tune過程所得到的 結果沒有差異。它們實際上與使用dbms_advisor.execute_task過程得到的結果是一樣的,但是對於 只優化一個SQL語句來說,快速優化這種方法更容易。其語法如下:

dbms_advisor.quick_tune (
advisor_name in varchar2,
task_name in varchar2,
attr1 in clob,
attr2 in varchar2 := null,
attr3 in number := null,
task_or_template in varchar2 := null);

下面是快速優化一個SQL語句的例子:

SQL> variable task_name varchar2(255);
SQL> variable sql_stmt varchar2(4000);
SQL> execute :sql_stmt := 'select count(1) cs  from bs_hospital a, bs_biztype g,  mt_biz_fin b, bs_center h, bs_insured j  where a.hospital_id = b.hospital_id    and  b.center_id = g.center_id    and b.biz_type = g.biz_type    and b.center_id =  h.center_id(+)    and b.valid_flag = ''1''    and b.indi_id = j.indi_id    and  (j.urban_type = ''all'' or ''all'' = ''all'')    and (b.district_code = b.center_id and  b.center_id in (430721) or    b.district_code <> b.center_id and b.center_id in (430721)  or b.district_code <> b.center_id and b.district_code in (430721)) and g.biz_stat =  ''2'' and b.biz_type <> ''52'' and b.biz_type <> ''17'' and b.pers_type_detail in (2)  and nvl(b.finish_flag, ''0'') = ''1'' and b.end_date between  to_date(''2014-01-01  00:00:00'', ''yyyy-mm-dd hh24:mi:ss'') and  to_date(''2014-12-31 23:59:59'', ''yyyy-mm- dd hh24:mi:ss'')';

PL/SQL procedure successfully completed
sql_stmt
---------
select count(1) cs  from bs_hospital a, bs_biztype g, mt_biz_fin b, bs_center h,  bs_insured j  where a.hospital_id = b.hospital_id    and b.center_id = g.center_id     and b.biz_type = g.biz_type    and b.center_id = h.center_id(+)    and b.valid_flag =  '1'    and b.indi_id = j.indi_id    and (j.urban_type = 'all' or 'all' = 'all')    and  (b.district_code = b.center_id and b.center_id in (430721) or    b.district_code <>  b.center_id and b.center_id in (430721) or b.district_code <> b.center_id and  b.district_code in (430721)) and g.biz_stat = '2' and b.biz_type <> '52' and b.biz_type  <> '17' and b.pers_type_detail in (2) and nvl(b.finish_flag, '0') = '1' and b.end_date  between  to_date('2014-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and  to_date('2014-12- 31 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
SQL> execute :task_name := 'my_quicktune_task';

PL/SQL procedure successfully completed
task_name
---------
my_quicktune_task
SQL> execute dbms_advisor.quick_tune(dbms_advisor.sqlaccess_advisor,:task_name,  :sql_stmt);

PL/SQL procedure successfully completed
task_name
---------
my_quicktune_task
sql_stmt
---------
select count(1) cs  from bs_hospital a, bs_biztype g, mt_biz_fin b, bs_center h,  bs_insured j  where a.hospital_id = b.hospital_id    and b.center_id = g.center_id     and b.biz_type = g.biz_type    and b.center_id = h.center_id(+)    and b.valid_flag =  '1'    and b.indi_id = j.indi_id    and (j.urban_type = 'all' or 'all' = 'all')    and  (b.district_code = b.center_id and b.center_id in (430721) or    b.district_code <>  b.center_id and b.center_id in (430721) or b.district_code <> b.center_id and  b.district_code in (430721)) and g.biz_stat = '2' and b.biz_type <> '52' and b.biz_type  <> '17' and b.pers_type_detail in (2) and nvl(b.finish_flag, '0') = '1' and b.end_date  between  to_date('2014-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and  to_date('2014-12- 31 23:59:59', 'yyyy-mm-dd hh24:mi:ss')


SQL> create or replace procedure show_recm (in_task_name in varchar2) is
  2  cursor curs is
  3   select distinct action_id, command, attr1, attr2, attr3, attr4
  4  from user_advisor_actions
  5  where task_name = in_task_name
  6  order by action_id;
  7
  8  v_action number;
  9  v_command varchar2(32);
 10  v_attr1 varchar2(4000);
 11  v_attr2 varchar2(4000);
 12  v_attr3 varchar2(4000);
 13  v_attr4 varchar2(4000);
 14  v_attr5 varchar2(4000);
 15  begin
 16   open curs;
 17   dbms_output.put_line('=========================================');
 18   dbms_output.put_line('Task_name = ' || in_task_name);
 19   loop
 20      fetch curs into
 21        v_action, v_command, v_attr1, v_attr2, v_attr3, v_attr4 ;
 22    exit when curs%notfound;
 23    dbms_output.put_line('Action ID: ' || v_action);
 24    dbms_output.put_line('Command : ' || v_command);
 25    dbms_output.put_line('Attr1 (name) : ' || SUBSTR(v_attr1,1,30));
 26    dbms_output.put_line('Attr2 (tablespace): ' || SUBSTR(v_attr2,1,30));
 27    dbms_output.put_line('Attr3 : ' || SUBSTR(v_attr3,1,30));
 28    dbms_output.put_line('Attr4 : ' || v_attr4);
 29    dbms_output.put_line('Attr5 : ' || v_attr5);
 30    dbms_output.put_line('----------------------------------------');
 31    end loop;
 32    close curs;
 33    dbms_output.put_line('=========end recommendations============');
 34  end show_recm;
 35  /

Procedure created

SQL> set serveroutput on size 99999
SQL> execute show_recm('my_quicktune_task');

=========================================
Task_name = my_quicktune_task
Action ID: 1
Command : CREATE MATERIALIZED VIEW
Attr1 (name) : "INSUR_CHANGDE"."MV$$_B1D10000
Attr2 (tablespace):
Attr3 : REFRESH FORCE WITH ROWID
Attr4 : ENABLE QUERY REWRITE
Attr5 :
----------------------------------------
Action ID: 2
Command : GATHER TABLE STATISTICS
Attr1 (name) : "INSUR_CHANGDE"."MV$$_B1D10000
Attr2 (tablespace):
Attr3 : -1
Attr4 :
Attr5 :
----------------------------------------
=========end recommendations============

PL/SQL procedure successfully completed