Oracle JDBC驱动使用setDate()、setTimestamp()导致全表扫描

今天有一个项目组报说,一个业务流程在Oracle上无法执行完成,而在SQL SERVER却非常的正常。

环境:ORACLE RAC 10.2.0.4.0 FOR AIX 64bit

于是开始查询是什么原因,该业务流程操作的表是一个非常大的表,亿级的数据量。通过对业务流程SQL执行的监控,发现在执行对这个表做小部分数据删除的SQL时候卡住不动了。查看了SQL的执行计划发现是全表扫描,没有建索引,于是把索引建上,重新监控,问题依然。

通过select exectutions from v$sqlarea where sql_id='xxxxxxx' 发现值为0。
检查select buffer_gets from v$sqlarea where sql_id='xxxxxxxx' 发现值一直在不停的增长。
说明这个SQL一次都没执行过,删除的数据只有很少的量,但是却一直在读数据,首先想到的是全表扫描。

于是让开发人员看了一下代码,这个SQL用到了预编译
PreparedStatement,where 条件要过滤一个时间字段,赋值的时候使用的是setDate()方法。在单独执行该SQL我使用的是to_date()函数来设置时间,执行速度很快,于是我让开发人员把代码中的SQL过滤时间的部分加入to_date()函数,使用setString()方法赋值,再监控,就变得非常正常了。

后来同事在网上g了一下,发现这是oracle jdbc驱动确实有这个问题。在Java使用预编译在where条件中使用setDate(),setTimeStamp()方法来给时间字段赋值都会导致在执行该SQL的时候对表进行全表扫描。

解决方法1:我们可以通过在SQL使用to_date('?','yyyy-mm-dd hh24:mi:ss')在绑定变量的时候使用setString()方法来代替使用setDate。

解决方法2:在配置连接的地方加入以下配置属性:


解决方法3:
try {
            Class.forName("oracle.jdbc.OracleDriver");
Properties prop=new Properties();
prop.setProperty("user","sysuser");
prop.setProperty("password","sys");
prop.setProperty("oracle.jdbc.V8Compatible","true");

java.sql.Connection connection1 = DriverManager.getConnection("jdbc:oracle:thin:@192.168.8.200:1521:cdb", prop);
System.out.println(connection1);
            System.out.println(connection1.getMetaData().getDriverName()+"
"+connection1.getMetaData().getDriverVersion());
ResultSet rs = connection1.createStatement().executeQuery("select date1,date2 from t_test");
rs.next();
printInfo(rs,1);
printInfo(rs,2);
}
catch (Exception exception1) {
exception1.printStackTrace();
}


解决方法4:
在系统变量中使用参数-Doracle.jdbc.V8Compatible="true",例如
java -Doracle.jdbc.V8Compatible="true" MyApp

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23135684/viewspace-629761/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/23135684/viewspace-629761/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值