前几天客户投诉我们提供的一个访问Oracle的程序,说运行太慢了,半天都没有处理完数据。
客户数据也就几十万条,也不是什么海量数据,究竟什么原因呢。而且奇怪的是我们提供的其它类似的程序访问同一张数据表却没有任何的问题。
经过多次反复写测试程序,尝试各种的条件,最后发现原来是其中一条update语句执行很慢,要2秒钟才更新一条。而这条update语句的where部分有两个条件,一个是整数的比较条件,一个是日期的比较条件。当然很容易就可以通过测试排除了整数条件导致慢的可能性。剩下的原因就是日期比较条件导致慢了。
说得也奇怪,日期条件是通过param的方式传入参数的,执行很慢。但测试的时候如果把日期条件展开,把日期条件变成SQL的一部分,那就执行很快了。先不论为什么这么奇怪,要知道Oracle SQL语句的日期条件不是一般的麻烦,都要经过TO_DATE/TO_CHAR糊弄来糊弄去,SQL语句跟其他的数据库不一样,程序就失去通用性了。一定是自己调用OCI的时候犯了什么糊涂错误了。
最后还是发现有一个不妥当的地方:数据库字段类型是DATE,而我用OCI绑定param的时候,用的却是SQLT_TIMESTAMP。原因是我想偷懒,希望用OraDateStruct就解决OCI的日期类型。于是我尝试用回SQLT_DAT,自己“笨笨的”把时间转换为OCI所能辨认的7个byte的数组,然后运行程序。速度太快了,一下子就执行完了。
其实不明白的是,Oracle发现类型不匹配,要不就报错;要不就把条件变为相容的数据进行查询。但是现在从现象看来,Oracle像是把所有保存的数据逐个转换成为与条件相容的类型进行判断,而不是转换条件的类型。所以每次update都变成了遍历所有的数据。难道是存在DBA可以调整的优化策略??不明白,不明白……