Oracle不同版本在驱动运行中如何使用JavaDate

本文主要介绍的是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类型且建立了索引。

 
 
 
  1. “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。

以上的相关内容就是对Oracle不同版本驱动中使用Java Date的问题的介绍,望你有所收获。

网站栏目:Oracle不同版本在驱动运行中如何使用JavaDate
标题链接:http://www.shufengxianlan.com/qtweb/news7/116057.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联