如果你在Oracle版本驱动中使用Java Date时产生一些问题的时候,你是否想了解不解之处,以下的文章主要是通过对Oracle版本驱动中使用Java Date的问题的实际应用的方案的介绍,来解答你在Oracle版本驱动中使用Java Date的问题在实际操作方面的问题。
这里两天都在对一条sql进行调优。该sql并不复杂,类似于
select ... from some_view union all select ... from some_table where datetime >= d1 and datetime< d2 and .... 底层使用
ibatis2.1.6 + oracle 10g 今天花了些时间继续研究这个问题,导致该问题的原因的确是“导致oracle对datetime字段进行了隐式类型转换,最终CBO未能使用该列的全局索 引”,不过问题不是出在ibatis上而是Oracle driver。设我们使用这样的sql通过绑定变量(类型为java.util.date)查询数据库,其中end_date是date类型且建立了索引。
“select count(*) from table1 where end_date >= :1 and end_date <= :2” 通常,面对这样的sql,我们希望它的执行计划走index range scan。然而在默认情况下oracle CBO是不会选择走索引地,以上面这语句为例,oracle实际走的是table full scan。为什么会这样 呢?这类问题是oracle版本在9.2以后引入了TIMESTAMP才开始出现的。
在 9.2之前,Oracle只有DATE,而没有TIMESTAMP。在jdbc preparedStatement.setTimestamp时,绑定变量的类型会被正确的设置为DATE。而在9.2之后,oracle开始支持 TIMESTAMP了,这两者都能支持精度为yyyy-MM-dd hh24:mi:ss的时间(当然TIMESTAMP能支持到纳秒级别)。
但jdbc driver的api未变同样在preparedStatement.setTimestamp时,oracle driver就得选择到底该把绑定变量的类型设置为DATE还是TIMESTAMP呢?估计是由于TIMESTAMP的精度更高,Oracle 最终默认选择了将绑定变量的类型设置为了TIMESTAMP。那么这个时候,如果面对实际属性为DATE的列,那么就会导致 oracle隐式地进行形如
“TO_TIMESTAMP(date_column) = parameter_timestamp” 转换,要 知道oracle CBO不会选择被某函数作用的列上的索引源码天空,除非是函数索引。因此,最终也会导致最上面的情况使用table full scan而不是index range scan。
Oracle版本就没有提供别的方法来正确地提供绑定变量吗?oracle提供 了几个方法来解决这个问题
1.升级到11g并使用新的正确的driver api。
2.将DATE列全都改成 TIMESTAMP列。
3.使用V8Compatible flag。
- public void setParameter(PreparedStatement ps, int i, Object parameter, String jdbcType)
- throws SQLException {
- ps.setTimestamp(i, new java.sql.Timestamp(((Date) parameter).getTime()));
- }
- SQL语句用了l_apiendtime>?并且使用setTimestamp会使索引失效,可以用to_date()函数来转换字符串为日期和date做比较
相关推荐
Oracle官方11g 最新版jdbc驱动。 新特性: 1、支持JDK6,支持JDBC 4.0,新的java.sql.SQLXML类型没有被支持,是使用ojdbc6.jar来支持。... 尽量使用和数据库版本一致的驱动,有bug时,换高版本的JDBC驱动试试 。
Oracle官方11g 最新版jdbc驱动。 新特性: 1、支持JDK6,支持JDBC 4.0,新的java.sql.SQLXML类型没有被支持,是使用ojdbc6.jar来支持。... 尽量使用和数据库版本一致的驱动,有bug时,换高版本的JDBC驱动试试 。
Oracle是能够安装在目前为止所有的计算机上并进行驱动运行的关系型数据库管理系统。Oracle数据库内部的数据操作可以通过sql语句执行处理,sql与C、Basic等语言不通,数据的访问方法和操作顺序不用正确指定,是要告诉...
有近20年使用Oracle技术产品以及Oracle数据库管理员/Oracle数据库应用管理员的经验,是真正应用集群、性能调优以及数据库内部属性方面的专家。同时是一位演讲家及Oracle ACE。 JARED STILL 从1994年就开始使用...
5.1.2 对象的产生和使用 110 5.1.3 对象、引用和指针 111 5.1.4 对象的this引用 112 5.2 方法详解 116 5.2.1 方法的所属性 116 5.2.2 方法的参数传递机制 116 5.2.3 形参长度可变的方法 120 5.2.4 递归方法 ...
在开发Java软件方面,Oracle的数据库提供了四种类型的驱动程序,二种用于应用软件、applets、servlets等客户端软件,另外二种用于数据库中的Java存储过程等服务器端软件。在客户机端软件的开发中,我们可以选择OCI...
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
10.3 使用TO_CHAR、TO_NUMBER 和TO_DATE转换函数 361 10.4 在SELECT语句中应用条件表达式 368 10.4.1 嵌套函数 368 10.4.2 条件函数 369 10.5 本章知识点回顾 375 10.6 自测题 376 10.7 自测题答案 378 第11...
10.3 使用TO_CHAR、TO_NUMBER 和TO_DATE转换函数 361 10.4 在SELECT语句中应用条件表达式 368 10.4.1 嵌套函数 368 10.4.2 条件函数 369 10.5 本章知识点回顾 375 10.6 自测题 376 10.7 自测题答案 378 第11...
Credit Suisse和Oracle曾试图为Java EE的配置创建一个宏伟的JSR标准,现在距离这个计划的破产已经过去了两年的时间。导致这个计划破产的原因很多,我们在这里的关注点也不是讨论它的细节。需要说明的是,尽管官方的...
如果各位想用其他数据库,可以自己加载其他数据库的驱动,并修改一下DbOption类下的getTableColumns(String)方法中的查询表信息方法 以及添加类似dm2java.properties数据库类型到java数据类型的映射文件,不同数据库...
除非您访问驱动器有问题,否则不要继续进行。向系统分区写入新的主引导记录可能破坏分区表并导致分区无法访问。 format 将指定的驱动器格式化为指定的文件系统。含有下列参数的 format 命令仅在使用故障恢复...
6.9.1 Java中的Date类 94 6.9.2 Java中的GregorianCalendar类 96 6.9.3 擅用系统已有类的思想 98 6.10 小结 99 第7章 访问控制——Java世界的卫兵 100 7.1 包的使用 100 7.1.1 声明创建包 100 7.1.2...
<jp:mondrianQuery dataSource="" id="query01" jdbcDriver="oracle.jdbc.driver.OracleDriver" jdbcUrl="jdbc:oracle:thin:ngykt/ngyktadmin@172.16.46.241:1521:orcl10" catalogUri="/WEB-INF/queries/feeSchema....