这么多步骤,也能写自动化脚本,感兴趣的可以自己尝试一下
1.确认一定要开启共享游标
beginEXECUTE IMMEDIATE ' alter session set "_optimizer_extended_cursor_sharing_rel"=none ';EXECUTE IMMEDIATE ' alter session set "_optimizer_extended_cursor_sharing"=none ';EXECUTE IMMEDIATE ' alter session set "_optimizer_adaptive_cursor_sharing"=false';EXECUTE IMMEDIATE 'alter session set cursor_sharing=FORCE ';end;
2.flush shared_pool的替代方式,方便找到代码助手产生的执行计划
DECLARECURSOR a_cur ISSELECT DISTINCT s.address || ',' || s.hash_value addrFROM v$sql sWHERE upper(s.sql_text) LIKE upper('%all_tab_columns%')AND s.sql_text LIKE '%:%'AND s.sql_text NOT LIKE '%v$sql%';BEGINFOR a_rec IN a_cur LOOPEXECUTE IMMEDIATE 'begin sys.dbms_shared_pool.purge(:1, ''c''); end;'USING a_rec.addr;END LOOP;END;
3.使用代码助手确认执行计划
fnd_lookup_values_vl.attribute2v$session.user#select * from v$instance k where k.blocked
4.找到sql_id
select s.sql_id ,s.plan_hash_value,s.child_number from v$sql s where upper(s.sql_text) like upper('%all_tab_columns%') and s.sql_text like '%:%' and s.sql_text not like '%v$sql%'SQL_ID PLAN_HASH_VALUE CHILD_NUMBERSQL_ID PLAN_HASH_VALUE CHILD_NUMBER8fqtv1mu1y2fv 1708561845 0
请自行替换后续的8fqtv1mu1y2fv 和1708561845为你环境的值
5.检查执行计划
select * from table(dbms_xplan.display_cursor('8fqtv1mu1y2fv','0','advanced'));1 SQL_ID 8fqtv1mu1y2fv, child number 02 -------------------------------------3 select column_name, nullable, data_type, data_type_mod,4 data_type_owner, data_length, data_precision, data_scale, char_used,5 char_length from sys.all_tab_columns where owner = :"SYS_B_0" and6 table_name = :"SYS_B_1" order by column_id78 Plan hash value: 1708561845910 ------------------------------------------------------------------------------------------------------------------11 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |12 ------------------------------------------------------------------------------------------------------------------13 | 0 | SELECT STATEMENT | | | | 1635 (100)| |
6.开始使用SPM优化助手优化
DECLAREtuning_task_name VARCHAR2(240);BEGINtuning_task_name := dbms_sqltune.create_tuning_task(sql_id => '8fqtv1mu1y2fv',plan_hash_value => '1708561845',scope => 'COMPREHENSIVE',time_limit => 300, --优化时间上线,单位秒task_name => 'SQLTURNING_CODE_ASSISTANT',description => 'optimize sql',con_name => NULL);END;
7.执行任务
begindbms_sqltune.execute_tuning_task(task_name=>'SQLTURNING_CODE_ASSISTANT');end;
8.查询任务
select * from user_advisor_log u where u.task_name='SQLTURNING_CODE_ASSISTANT';
9.打印结果
select dbms_sqltune.report_tuning_task('SQLTURNING_CODE_ASSISTANT') from dual;
10.找到关键词“SQL Profile Finding”,
比如我的长这样
1- SQL Profile Finding (see explain plans section below)--------------------------------------------------------A potentially better execution plan was found for this statement.Recommendation (estimated benefit: 77.34%)------------------------------------------- Consider accepting the recommended SQL profile.execute dbms_sqltune.accept_sql_profile(task_name =>'SQLTURNING_CODE_ASSISTANT', task_owner => 'APPS', replace =>TRUE);
你能看到更多信息
旧成本Plan hash value: 1062139556
-------------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-------------------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 2 | 714 | 7435 (1)| 00:00:01 |
优化后的新成本Plan hash value: 4146289287
-----------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 357 | 292 (1)| 00:00:04 |
11.执行sql配置更改
begindbms_sqltune.accept_sql_profile(task_name =>'SQLTURNING_CODE_ASSISTANT', task_owner => 'APPS', replace =>TRUE);end;
12.检查执行计划
select* from v$sql s where s.sql_id='8fqtv1mu1y2fv';--子游标1性能更好select * from table(dbms_xplan.display_cursor('8fqtv1mu1y2fv','0','advanced'));select * from table(dbms_xplan.display_cursor('8fqtv1mu1y2fv','1','advanced'));
13.计划基线捕获
declarel_plans_loaded pls_integer;beginl_plans_loaded:=dbms_spm.load_plans_from_cursor_cache(sql_id=>'8fqtv1mu1y2fv'); --这里有参数可以直接固定,我为了演示没有使用fixed=>'YES'dbms_output.put_line(l_plans_loaded);end;
14.检查计划基线
SELECT sql_handle,plan_name,enabled, -- 指示计划基准是已启用(YES)还是已禁用(NO)accepted, -- 表示计划基线是否被接受(YES)否(NO)fixed, -- 指示计划基准是否固定(YES)(NO)substr(sql_text,1,100)FROM dba_sql_plan_baselines sWHERE upper(s.sql_text) like upper('%all_tab_columns%') and s.sql_text like '%:%' and s.sql_text not like '%v$sql%'SQL_HANDLE PLAN_NAME ENABLED ACCEPTED FIXEDSQL_a66bfc0020f65c85 SQL_PLAN_acuzw00hgcr453ebe2368 YES YES NOSQL_a66bfc0020f65c85 SQL_PLAN_acuzw00hgcr458b0d60a7 YES YES NO
15.检查并找到性能较好的执行计划对应的基线
select * from table(dbms_xplan.DISPLAY_SQL_PLAN_BASELINE(plan_name => 'SQL_PLAN_acuzw00hgcr453ebe2368',sql_handle =>'SQL_a66bfc0020f65c85' ) );select * from table(dbms_xplan.DISPLAY_SQL_PLAN_BASELINE(plan_name => 'SQL_PLAN_acuzw00hgcr458b0d60a7',sql_handle =>'SQL_a66bfc0020f65c85' ) );--此成本较低,性能好
可以看到执行计划从跳跃扫描变成了索引顺序扫描,同时驱动顺序变化(正常的执行计划应该是顺序扫描才对,因为索引的先导列就是name,不应该执行跳跃扫描,正常情况下优化我直接写hint完事了)
16.固定计划基线
declarel_plans_altered pls_integer;beginl_plans_altered:=dbms_spm.alter_sql_plan_baseline(sql_handle =>'SQL_a66bfc0020f65c85' ,plan_name =>'SQL_PLAN_acuzw00hgcr458b0d60a7' ,attribute_name =>'fixed' ,attribute_value =>'YES' );end;
17.重复步骤2,3,然后检查新产生的执行计划
select s.sql_id ,s.plan_hash_value,s.child_number from v$sql s where upper(s.sql_text) like upper('%all_tab_columns%') and s.sql_text like '%:%' and s.sql_text not like '%v$sql%'select * from table(dbms_xplan.display_cursor('8fqtv1mu1y2fv','0','advanced'));
优化完成
SQL_ID 8fqtv1mu1y2fv, child number 0-------------------------------------select column_name, nullable, data_type, data_type_mod,data_type_owner, data_length, data_precision, data_scale, char_used,char_length from sys.all_tab_columns where owner = :"SYS_B_0" andtable_name = :"SYS_B_1" order by column_idPlan hash value: 4146289287-----------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | 292 (100)| |
18.可以自行尝试修改代码助手的delay,由默认的500毫秒改成100毫秒甚至更低,
现在我的开发环境,代码助手弹出column直接起飞,完全不卡,以前是5-10秒,非常卡顿,优化效果非常好(如果我能拿到trace就更有说服力)
如果还是存在卡顿,请按前面的教程,跑trace然后自行分析
另外package的代码助手优化原理一模一样,这里不再赘述
select from fnd_lookup_types_vl flv where flv.lookup_type
文章转载自云贝教育,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




