_optim_peek_user_binds导致的性能问题
Tags: Oracle
案情:
客户新业务上线(数据库版本为 10.2.0.5)一段时间后,系统CPU都在20%左右。19日,系统CPU使用率突然接近100%,交易处理速度也严重下降。20日凌晨1:15分之后,系统CPU突然又降到20%左右,交易速度也有大幅提高(只有几毫秒);
21日凌晨2点左右又变慢,直到22日下午对相关表做truncate后,应用也做了代码调整(处理完的交易记录马上删除,表始终保持较小的状态),系统才恢复稳定运行。
对于20日凌晨系统性能突然变好的问题,某服务公司已经给出一份报告,怀疑是当时开发人员对业务相关表做了truncate操作(大表数据量小了,消耗的资源就少),然而开发人员表示没有做任何操作。到底研发人员有没有做truncate表操作?事情的根本原因是什么?客户需要对这个问题重新分析,给出明确的结论。
根据当时收集的信息,19日的 CPU使用率高主要是由下面的SQL引起:
select CCYGRP ,QUTSEQ ,SELRAT ,BUYRAT ,BOKRAT
from FXTTRT
where (CCYGRP=:b0 and DELTYP='R')
order by QUTSEQ;
使用的是全表扫描的执行计划。在业务繁忙时段,有很多并发进程在执行这个个SQL,FXTTRT表有100多万条记录,而且还在不断增加,CPU使用率高是预期行为。
根据sqlhc工具收集的信息,下面FXTTRT表的统计信息的历史数据可以说明,17日到23日,表的数据在持续增长,20日发生truncate表操作的可能性非常小(除非先对表做了备份,truncate表后,在收集统计信息前又重新插回来):
结合研发人员声称没有做truncate操作,上面信息已经基本推翻了原报告怀疑FXTTRT表被truncate的结论(可以看出16日前做过一次truncate操作)。
因为AWR在当前系统只保留一周,4月1日案情重审时已经找不到19日和20日的执行计划,只有一些当时分析问题时收集的SQL执行效率的数据,红框内20日的SQL执行效率高前后两天19日和21日好多2倍:
根据性能数据的巨大差别可以推断,如果当时表没有做truncate,一定是执行计划发生了改变,使用了更好的执行计划。我们来看看是否有更好执行计划的可能:
表字段统计信息:
因为两个谓词条件使用的字段唯一值较小,所以第一次的分析认为走全表扫描就是最好的执行计划(如果字段上的数据分布均匀,唯一值这么小的字段确实不适合使用索引)。
表上的索引,谓词条件的两个字段是索引的前两个字段:
再看看表上两个字段的实际数据分布情况: