今天在生产环境一段平时表现良好的程序,出现了性能问题,在loop循环中死活执行不完,这个loop循环大概需要循环40W次,
在循环里面执行的sql大致为:
update t_object set ****
where owner=:a
and object_type=:b
and object_id = :c
其中(owner,object_type)建了索引N1,(object_id)建有索引N2,从生产环境抓取的执行计划,可以看到对于表t_object采用的
是索引N1的范围扫描,通过观察绑定变量,发现通过索引N1过滤出来的数据还是达到几十万之多!这样的扫描方式显然是低效的,
但是为什么优化器不采用索引N2去扫描数据了,这样过滤出的数据将很少,执行效率肯定比用N1快的多。
后来通过观察表的字段发现object_id的字段类型为varchar2,而绑定变量:c的数据类型是number,这样oracle就自动进行了隐式转换,
从而忽略掉了索引N2,导致了这次性能问题!原来在上个版本,为了程序的兼容性,我们将字段的object_id的字段类型从number变更
为了varchar2类型,但是忘记了这个索引!!后来没办法只能变更程序
update t_object set ****
where owner=:a
and object_type=:b
and object_id = to_char(:c)
才让这段逻辑顺利执行完毕,教训呀。。。希望大家也能引以为戒。。。。