jdbc查询时,传入Date类型导致索引失效

博客探讨了在Oracle数据库中查询慢的问题,原因是java.util.Date与数据库date列之间的隐式转换导致索引无法有效利用。解决方案包括修改数据库列类型、使用to_date函数、转换传入参数类型或使用cast函数。建议避免隐式转换,以提高查询效率。
摘要由CSDN通过智能技术生成

发现明明有索引,当但是查询还是很慢。花费了几个小时。终于找到原因了。

之前试过使用强制索引。但是无效。

select /*+index(fy IDX_JFRQ)*/ *from tab fy where jfrq>?

网上找到原因:

由于需要小时分秒的信息,我们使用的是java.util.Date,观察发现在数据库端有类似如下函数转换

  1. TO_TIMESTAMP(date_column) = parameter_timestamp

导致纵然加了hit也走不上索引.

为什么会触发oracle做隐式转换呢?因为在ibatis的处理中,java.util.Date会转换为java.sql.Timestamp(具体原因可以参考java.sql.PreparedStatement和相关文档,在此不详述)

  1. ps.setTimestamp(i, new java.sql.Timestamp(((Date) parameter).getTime()))

JAVA传下去的是Timestamp,而数据库的类型是Date,根据oracle的策略,会对date类型做强制转换TO_TIMESTAMP(GMT_SEND),因此就走不上索引了 。

解决方案:
        经过网上查询,认为可选且比较靠谱的解决方案主要有三种:
a.将数据库的列改为timestamp(修改了业务逻辑,该字段只要日期,不需要时间)
b.使用to_date('2020-03-08','yyyy-mm-dd')

to_date(to_char(?,'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD HH24:MI:SS');

c.将传入参数由java.util.Date转换为String,然后在ibatis端使用to_date函数解决(改动点太多)

and fjrq >= to_date(?,'YYYY-MM-DD HH24:MI:SS')

d.给GMT_SEND字段建函数索引(为了走索引而走索引,不是正常的解决问题的办法)

e.cast函数转成Date类型,最终是采用这种方案,对现有程序功能无影响且直接解决问题

and jfrq >= cast(? as date)

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值