oracle利用INLIST ITERATOR优化SQL
来源:互联网 发布:sql server是什么软件 编辑:程序博客网 时间:2024/06/06 07:08
开发人员反应一支查看bom的sql反应很慢,需要dba协助优化。
SQL如下:
SELECT A0.idA2A2,A0.updateCountA2,A0.classnameA2A2,ABS(NULL),A0.branchIdA2typeDefinitionRefe,A1.idA2A2,A1.updateCountA2,A1.idA3A6,A1.value FROM WTPartUsageLink A0,BooleanValue A1 WHERE (((A1.idA3A6 = :1 ) AND (A1.idA3A4 = A0.idA2A2) AND ((A1.idA3A5 = :2 ) OR (A1.idA3A5 IS NULL )))) AND (A0.markForDeleteA2 = 0) AND (A0.idA2A2 IN (:3 ,:4 ,:5 ,:6 ,:7 ,:8 ,:9 ,:10 ,:11 ,:12 ,:13 ,:14 ,:15 ,:16 ,:17 ,:18 ,:19 ,:20 ,:21 ,:22 ,:23 ,:24 ,:25 ,:26 ,:27 ,:28 ,:29 ,:30 ,:31 ,:32 ,:33 ,:34 ,:35 ,:36 ,:37 ,:38 ,:39 ,:40 ,:41 ,:42 ,:43 ,:44 ,:45 ,:46 ,:47 ,:48 ,:49 ,:50 ,:51 ,:52 ,:53 ,:54 ,:55 ,:56 ,:57 ,:58 ,:59 ,:60 ,:61 ,:62 ,:63 ,:64 ,:65 ,:66 ,:67 ,:68 ,:69 ,:70 ,:71 ,:72 ,:73 ,:74 ,:75 ,:76 ,:77 ,:78 ,:79 ,:80 ,:81 ,:82 ,:83 ,:84 ,:85 ,:86 ,:87 ,:88 ,:89 ,:90 ,:91 ,:92 ,:93 ,:94 ,:95 ,:96 ,:97 ,:98 ,:99 ,:100 ,:101 ,:102 ,:103 ,:104 ,:105 ,:106 ,:107 ,:108 ,:109 ,:110 ,:111 ,:112 ,:113 ,:114 ,:115 ,:116 ,:117 ))
利用以下脚本,查看到sql执行情况,确认很慢。
Select inst_id, sql_id, child_number chld, plan_hash_value plan_hash, users_executing exe, executions exes,
parsing_schema_id user_id,
buffer_gets/executions gets,
disk_reads/executions reads,
rows_processed/executions rows_, cpu_time/executions/1000/1000 cpu_ms,
Elapsed_time/executions/1000/1000 elaps_ms,
USER_IO_WAIT_TIME/executions/1000/1000 io_ms,
last_load_time,
to_char(sysdate,'hh24:mi:ss') chk_date
From gv$sql
Where sql_id='dm5fk9c92c7yk'
and executions>0
order by last_load_time
原执行计划如下:
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | NESTED LOOPS | | 1 | 70 | 2 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 1 | 70 | 2 (0)| 00:00:01 |
|* 3 | TABLE ACCESS BY INDEX ROWID| BOOLEANVALUE | 1 | 28 | 1 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | BOOLEANVALUE$COMPOSITE2 | 1 | | 1 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN | PK_WTPARTUSAGELINK | 1 | | 1 (0)| 00:00:01 |
|* 6 | TABLE ACCESS BY INDEX ROWID | WTPARTUSAGELINK | 1 | 42 | 1 (0)| 00:00:01 |
其实这个问题主要是in后面的参数值有100多个,执行计划中并没有走INLIST ITERATOR(迭代)操作,迭代是指in后有多个常量时,只执行一次,而不走迭代时,有多少个常量就要执行多少次。显然,执行计划走迭代性能要好。
手工尝试输入三个参数值代入in中时,发现执行计划有走迭代,而v$sql中只有一个执行计划,无法从cursor中去选择一个好的执行计划来加以固化,询问过开发人员,这是一支由系统自动生成的sql,无法手工去修改SQL,而oracle也没有提供INLIST ITERATOR的hint,手工调整已无法实现,只能依靠oracle本身的优化工具。
通过自动sql tuning和sql profile调整执行计划:
1.针对sql_id建立自动sql tuning任务:
declare
tuning_task_name varchar2(30);
tuning_sqltext clob;
begin
tuning_task_name :=dbms_sqltune.create_tuning_task(
sql_id => 'dm5fk9c92c7yk',
scope =>'COMPREHENSIVE',
time_limit =>2000,
task_name =>'plmsq2',
description=>'Tune T1 count');
end;
2.执行自动sql tuing任务
begin
dbms_sqltune.execute_tuning_task(task_name=>'plmsq2');
end;
3.查询tuing任务完成报告
select dbms_sqltune.report_tuning_task('plmsq2')
from dual
4.比较报告中执行计划好坏,并接受profile:
execute dbms_sqltune.accept_sql_profile(task_name => 'plmsq2', task_owner
=> 'ZENGXUEWEN',force_match=>true,replace => TRUE);
5.查询profile情况
select * from dba_sql_profiles order by created
查得已针对sql建立的profile为SYS_SQLPROF_01560c5445fd0001
调整后的执行计划:
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 47 (100)| |
| 1 | NESTED LOOPS | | 62M| 4147M| 47 (3)| 00:00:01 |
| 2 | NESTED LOOPS | | 62M| 4147M| 47 (3)| 00:00:01 |
| 3 | INLIST ITERATOR | | | | | |
|* 4 | TABLE ACCESS BY INDEX ROWID| BOOLEANVALUE | 96 | 2688 | 18 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | BOOLEANVALUE$COMPOSITE0 | 128 | | 15 (0)| 00:00:01 |
|* 6 | INDEX UNIQUE SCAN | PK_WTPARTUSAGELINK | 1 | | 1 (0)| 00:00:01 |
|* 7 | TABLE ACCESS BY INDEX ROWID | WTPARTUSAGELINK | 648K| 25M| 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------
优化前后性能对比:
调整前(单次执行):
所花时间:5458.77s cpu时间:630.589s 逻辑读:3914415.7 物理读:680683.438
执行计划调整后(单次执行):
所花时间:39.82ms cpu时间:13.86 ms 逻辑读:309 物理读:5.6
调整执行计划后,开发人员反馈变快了。
以下是QQ聊天记录:
- oracle利用INLIST ITERATOR优化SQL
- INLIST ITERATOR与CONCATENATION区别
- 关于Inlist iterator操作
- Inlist的绑定优化(书摘备查)
- Oracle 建立索引及利用索引的SQL语句优化
- Oracle 建立索引及利用索引的SQL语句优化
- 利用分区优化SQL
- 利用OWI优化SQL
- 利用 Oracle EM 企业管理器 进行oracle SQL的优化(自动生成索引)
- 利用 Oracle EM 企业管理器 进行oracle SQL的优化(自动生成索引)
- ORACLE SQL性能优化
- oracle sql优化
- oracle SQL性能优化
- oracle SQL性能优化
- oracle SQL性能优化
- oracle SQL性能优化
- oracle SQL性能优化
- oracle SQL性能优化
- JSON语法及其在android下的解析-->笔记一
- 并发集合
- 书店管理实例(TreeMap树状映射表)
- 十大开源安卓应用程序的开发框架
- Spark的Master分析2(Master注册机制原理分析)
- oracle利用INLIST ITERATOR优化SQL
- 一起talk C栗子吧(第一百七十七回:C语言实例--字符及字符串输入函数二)
- 关于杭州的记忆
- 【MySQL】在windows系统中安装压缩版MySQL并修改root可以在远程访问
- mysql-数据备份系列
- 从输入URL到页面加载完的过程
- Sort Algorithm-->Select Sort
- LeetCode: Best Time to Buy and Sell Stock II
- 自定义button相关