Delphi 程序错误写法造成Oracle数据库负载异常
注意:本文涉及的问题在9i的环境中测试的,经验证,同样适用于11g.
在用Toad的SGA Trace工具监控我们的Oracle 9.2.0.8 Patch 31古董数据库时发现一条奇怪的SQL,它占到数据库整体逻辑读50%以上,SQL如下: 这条SQL单次执行逻辑读不到900,但执行非常频繁,它本意想查询HRM.ORGANIZATION表的表与索引信息。 程序员应该不会特意写这种SQL,那它到底来自哪里? 通过MODEL_NAME,找到SQL对应的Session,并做10046 Trace分析这条SQL与 SELECT departmentname FROM hrm.organization WHERE departmentid=:1交替执行。DB层面已经很难再有什么有价值线索,只有请开发提供源码分析。 分析Delphi程序在执行以下语句时调用了异常SQL。 ADOQuery2.SQL.Add(str_4); ADOQuery2.Open; ADOQuery2.First; 程序员正确使用了Delphi ADOQuery控件添加了SQL文本,并调用Open方法执行SQL,但为何要再调用First方法? ADOQuery的First方法本意为定位到结果集的第一条记录。因为departmentid为主键,SELECT必返回一条记录,此步应为多余。请开发人员屏蔽掉ADOQuery2.First;再上线新版程序观察。 仔细分析此段程式,ADOQuery2调用Select语句时并没有使用绑定变量,是否是因为SQL硬解析造成异常SQL调用? 第三天这条诡异SQL又被监控到,到底是哪里还有问题,还是解决问题的思路错了?再回到前一天改过的源码...... 文本改为绑定变量没有错,是否Delphi ADOQuery控件执行Add方法时这条奇怪的SQL被调用?依据这个思路,再修改第三版程序,将ADOQuery 的Add方法调用放到While循环外,并请程序员重新编译上线。 现在在While循环外定义SQL,在While循环内给变量赋值并执行SQL。 Remark: 因为我们还有Informix 7 史前数据库,公司Policy规定不可用ODBC访问接口直接访问它,且Oracle 11.2 Gateway又不支持对Informix 7的访问,所以只有保留Oracle 9.2.0.8以利用其异构服务访问Informix 7。






