一次Oracle SQL优化的经验
前些时候候遇到一个SQL的性能问题,在解决过程里了解到了一些东西。有数据库表T,主键是列A, B, C, D, E。每天需要定时从上游数据库源取数据过来更新,大约10几万条。更新的操作过程是,对每条上游数据按几个关键字段在表T中进行删除操作。delete from T where B = ? and C=? and E = ??然后再进行Insert操作。
?????? 系统运行到三个多月的时候,遇到了问题。UAT环境(Oracle 10g)性能正常,10万条记录更新是10多分钟,Production环境(Oracle 9i,还没来得及升级), 有一天突然从10多分钟变成了一个小时,用户无法接受。首先确认了表的统计信息都是最新的,在分析查询计划后,发现性能下降主要由delete操作引起的,10g在优化中找到了索引,而9i在优化中用了CBO,全表扫描。试着改成强制使用RBO,还是没有用到索引。后来想到,可能是因为列A没有在where条件中,而我们除了主键以外,没有建另外的索引,所以聚集索引匹配的时候,第一个字段没有匹配上,就放弃使用索引了。而10g的优化器聪明一些,第一个列没找到后,还尝试了继续匹配。于是试着在where中加上A=?这人条件,再执行,果然用上索引了。由于A条件放在where中没什么意义,所以后来的解决办法是在区别度比较大的列C上单独加了一个索引,再执行时速度有明显提升,从一个小时回到了10多分钟。
?