今天是正式进入工作状态的一周的开始,上一周事务性的东西太多,因此只是初步对本次优化工作有了一个初步的想法。本周要完成系统性能分析报告和系统性能评估指标手册,这是我们这个项目向客户提交的第一部分技术性报告,报告的内容可能会作为评价我们本次优化工作的基础,因此需要十分细致。我和老于决定每人完成其中的一分报告,我负责完成系统性能分析报告。
我的计划是按部就班的一步一步来,先进行性能分析,确定优化的最佳路径,然后出优化方案,优化方案必须经过评审,评审后的优化方案需要甲方、集成商和我们四方签字,然后再共同制定实施计划,进行实施,这也是我一贯的工作方式,但是实际上根本无法按照我的思路进行。对于这个病入膏肓的系统,有时候就像救火一样,只能是该出手时就出手了。今天突然爆发了IBSS系统的性能问题,最初我们认为性能问题最严重的是销账系统,IBSS系统各方面指标还可以,今天的一个突发事件,完全颠覆了我的初步印象。今天下午突然报障说IBSS系统性能十分差,营业前台出现了大面积的排队,希望我们能够尽快协助处理一下。
通过STATSPACK报告以及OEM PERFORMANCE MANAGER的实时监控,发现今天的系统负载比平时高出30%左右,CPU/IO都出现了较为严重的问题。我问用户,今天业务量比平时高出这么多,是不是有什么特殊的业务,客户那边的反馈是没有听说有什么特殊的活动,这个回答使我们走了很多弯路,经过一个多小时的分析,我再次确定肯定是存在什么特殊的业务,否则不可能出现这种情况,从TOP SQL上看,目前排在前几位的SQL也是平时在TOP SQL中看不到的。再次和客户确认后,终于找到了答案,这几天的刮刮卡业务十分火爆,而我们看到的几个TOP SQL都是刮刮卡相关的。
通过调整了部分索引后,这几个SQL的性能有了明显的改善,CPU也出现了久违的IDLE,系统性能得到了明显的改善。在调整索引的过程中,我发现这几张相关的表上都有很多索引,但是都是单列索引,由于这些SQL的WHERE条件涉及到多个列,因此很多SQL都是通过几个单列索引扫描,然后取交集(AND_EUQ操作),这样的索引,效率就相对较低,甚至我发现BANK_ACCT_ID和BANK_ACCT_ID_SEQ这两个基本上在一起使用的字段,都没有创建复合索引,而是建立了两个独立的索引。经过了几层协调,当我终于找到了开发这个模块的开发人员的,我询问开发人员为什么要设计这样的索引,而不使用复合索引。开发人员的回答让我感到震惊,他说“我不知道什么叫复合索引,我为每个字段都建了索引,Oracle就应该能用到索引了”。从他的回答上我感到他根本不理解索引的概念,甚至很可能这个项目的整个开发团队都可能对索引知之甚少,因此他们设计出来的索引可能存在很严重的问题,今天暴漏出来的可能只是冰山一角。我马上和老肖讨论了这个问题,决定马上对IBSS系统的索引进行监控,看看这个系统中的近2000个索引,到底哪些索引是被用到的,哪些根本没有用到,在下一步的SQL优化工作中,索引优化将成为一个重点。
本节技术附注:
从Oracle 9i开始,可以监控Oracle索引的使用情况,具体方法如下:
alter index <schema>.<index> MONITORING USAGE;
对某个INDEX开启监控后,就可以观察该INDEX是否被使用:
select index_name,monitoring,used,start_monitoring,end_monitoring
from v$object_usage;
INDEX_NAME MONITORING USED START_MONITORING END_MONITORING
----------------------------------------------------------------------------------------
AA NO YES 06/04/2006 12:02:38 06/05/2006 13:47:39
AA1 NO YES 06/04/2006 12:02:40 06/05/2006 13:47:39
要注意的是,由于V$OBJECT_USAGE视图限制了只显示当前用户下被监控的索引的情况,因此,通过其他用户登录数据库,将无法看到,如果要查看所有用户下的被监控的索引的情况,使用如下SQL:
select u.name owner, io.name index_name, t.name table_name,
decode(bitand(i.flags, 65536), 0, 'NO', 'YES') monitoring,
decode(bitand(ou.flags, 1), 0, 'NO', 'YES') used,
ou.start_monitoring start_monitoring,
ou.end_monitoring end_monitoring
from sys.user$ u, sys.obj$ io, sys.obj$ t, sys.ind$ i, sys.object_usage ou
where i.obj# = ou.obj#
and io.obj# = ou.obj#
and t.obj# = i.bo#
and u.user# = io.owner#
如果要取消对索引使用情况的监控,使用下列SQL:
alter index <schema>.<index> NOMONITORING USAGE;
要注意的是:索引使用情况监控,会增加部分系统开销。
转载于:https://blog.51cto.com/hyuhan/113593