1. 问题描述:
系统的IO的IO量很大,经常性地,IO的吞吐量达到每秒300M以上。
通过AWR报告,找到问题集中在一条SQL上。
问题来了,我们不是做开发的,这个业务系统的业务逻辑我们也不清楚,我们可以优化么?
答案是可以的,
实际上我们完全在可以不懂业务逻辑的情况下完成绝大部分情况的优化,我们只要获得SQL执行的过程和明细即可快速完成优化,以下这条最占IO的SQL的优化我们在1分钟内就完成了优化。
为了说明我们不需要了解业务逻辑也可以完成优化,你会发现从头到尾没有看到过任何的SQL语句 ^_^
2. 优化过程:
获取执行计划和执行明细(哪些步骤消耗多少时间,花费多少IO)
可以看到:
上述SQL的执行时间是39秒,其中id=14的步骤,占了38秒,必须优化掉该瓶颈步骤。
Id=14的步骤,reads为1750K个BLOCK,即读了1750K*8K=13G,单次执行13G,38秒读完,即每秒的IO达到359M,但是最后只返回了6条记录,该步骤对A表进行全表扫描,显然,读取13G,应用了过滤条件后,最后只返回了6条记录!很多数据在读取到内存后基本都被丢弃了。缺少定位数据的高效方式,而索引是最适合定位少量数据的。
3. 优化方式
上图id=14的谓词部分,即红色加框部分,可以看到对A表扫描了13G,主要的过滤条件是c_captialmode和c_state这两个字段把大部分数据全滤掉了,因此创建复合索引即可,命令如下
Create index idx_1 on A(c_captialmode,c_state) tablespace &tbs online; |
4. 优化效果
优化后,每次执行,IO从13G下降至0 ;
优化后,执行时间从50秒下降至50毫秒
优化后,整个系统的IO从每秒359M下降到1M以下。
知识点:
在不了解业务逻辑的情况下,也可以快速实现对最消耗IO的SQL语句的快速优化。 精通数据库知识的DBA往往比不懂数据库原理的开发和程序员更懂SQL优化。 |