一个Date类型的ibatis查询走不上索引的问题

标签: date 类型 ibatis | 发表时间:2015-12-03 21:06 | 作者:bijian1013
出处:http://www.iteye.com

        实际工作中,发现Date类型作为条件查询走不上索引的问题,由于问题完全和 http://blog.csdn.net/zldeng19840111/article/details/6721589一样,为简便起见,直接采用它的实例说明。

        以下为简化后的场景:通过时间范围作一个邮件发送数量的统计

java:

import java.util.Date;

public List<Object> listRecentTaskInfoByStatus( Date start, Date end,String sendType) {

        Map<String,String> paraMap = new HashMap<String,String>();
        paraMap.put(TASK_STAT_START_TIME, start);
        paraMap.put(TASK_STAT_END_TIME, end);
        return defaultDao.getObjList(nameSpace.get(sendType), paraMap, "CHANNEL_RECENT_STAT");
}

ibatis:

<select id="SELECT_CHANNEL_RECENT_STAT" resultMap="MtnPlanSendlog_RM_CHANNEL_TASK" parameterClass="java.util.HashMap">
 <![CDATA[
 SELECT /*+index (a SENDLOG_GSEND_IND)*/
     overview_id,
     count(*) as tmp_count
  FROM
     MTN_PLAN_SENDLOG a
  WHERE
     is_deleted = 'n'
     and overview_id is not null
     and GMT_SEND >= #startTime#
     and GMT_SEND < #endTime#
     GROUP BY overview_id
  ]]>
</select>

 

现象:
        sql查询缓慢,DBA观察发现没有走上GMT_SEND的索引

 

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

TO_TIMESTAMP(date_column) = parameter_timestamp

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

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

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

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

 

解决方案:
        经过网上查询,认为可选且比较靠谱的解决方案主要有三种:
a.将数据库的列改为timestamp(风险较太大)
b.使用to_date('2011-03-08 15:45:43.123','yyyy-mm-dd HH24:MI:SS....')
c.将传入参数由java.util.Date转换为String,然后在ibatis端使用to_date函数解决   

and GMT_SEND >= to_date(#startTime#,'YYYY-MM-DD HH24:MI:SS')


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [date 类型 ibatis] 推荐:

一个Date类型的ibatis查询走不上索引的问题

- - 数据库 - ITeye博客
        实际工作中,发现Date类型作为条件查询走不上索引的问题,由于问题完全和 http://blog.csdn.net/zldeng19840111/article/details/6721589一样,为简便起见,直接采用它的实例说明.         以下为简化后的场景:通过时间范围作一个邮件发送数量的统计.

ibatis和mybatis区别

- - SQL - 编程语言 - ITeye博客
简介: 本文主要讲述了 iBatis 2.x 和 MyBatis 3.0.x 的区别,以及从 iBatis 向 MyBatis 移植时需要注意的地方. 通过对本文的学习,读者基本能够了解 MyBatis 有哪些方面的改进,并能够顺利使用 MyBatis 进行开发. 本文更适合有 iBatis 基础的开发人员阅读.

ibatis入门示例

- - CSDN博客架构设计推荐文章
一.什么是ibatis:.  iBatis 是apache 的一个开源项目,一个O/R Mapping 解决方案,iBatis 最大的特点就是小巧,上手很快. 如果不需要太多复杂的功能,iBatis 是能够满足你的要求又足够灵活的最简单的解决方案,现在的iBatis 已经改名为Mybatis 了. 二.ibatis和hibernate的对比:.

iBatis与MyBatis区别

- - 非技术 - ITeye博客
iBatis 框架的主要优势:. 1、iBatis 封装了绝大多数的 JDBC 样板代码,使得开发者只需关注 SQL 本身,而不需要花费精力去处理例如注册驱动,创建 Connection,以及确保关闭 Connection 这样繁杂的代码. 2、从 iBatis 到 MyBatis,不只是名称上的变化,MyBatis 提供了更为强大的功能,同时并没有损失其易用性,相反,在很多地方都借助于 JDK 的泛型和注解特性进行了简化.

关于date4j,简约的日期处理库(Java's Date Classes Must Die.)

- - BlogJava-首页技术区
      在熟悉公司业务代码的时候经常看见有日期处理(date),由于项目转手次数较多,在这方面没合理封装处理好,于是就想自己封装一个date类. 然而辗转了几天却发觉已经有date4j的存在,于是在这里简单地介绍一下这个日期类库. 以下包括自己的代码、网上流传资料、以及date4j官网例子.      比较常用的是java.util.date,将java.util.Date转为java.sql.Date的时候,日期时分秒会被去掉,失去精度.

Redis 数据类型

- - ITeye博客
该文章是对Redis官方文档的翻译. 字符串是Redis值的最基础的类型. Redis字符串是二进制安全的,这意味着一个Redis字符串可以包含任何种类的数据,例如一个JPEG图像或者一个序列化的Ruby对象. 一个字符串值最多可以保存512M字节的内容. 你可以使用Redis的字符串做一些有趣的事情,例如你可以:.

Java 类型信息

- - CSDN博客移动开发推荐文章
*  为什么需要运行时识别对象和类的信息. 多态 - 实例都被向上转型为父类引用,实例调用相应方法时,需要知道当前父类型引用的具体类型,并从中查找相应方法. IDE - 获取任意类的所有字段和方法.  跨网络的远程平台上创建和运行对象的能力. 从磁盘文件,或者网络连接中获取一串字节(表示类). * 运行时识别对象和类的信息的两种方式:.

宝贝挖鼻孔类型

- rokeyhu - 碌碡画报

JavaScript类型总览(图)

- Lionheart - aimingoo的专栏
这个图来自于《JavaScript语言精髓与编程实践》第三章P184页. 最近在改第二版,这张图重做了,需要的可以对照着看. 关注这个体系的朋友可以参考如下:. 再谈JavaScript的数据类型问题. 三谈类型问题:ECMAScript为什么错了. 此外,补充一下图中用到的概念:. 1、内置(Build-in)对象与原生(Naitve)对象的区别在于:前者总是在引擎初始化阶段就被创建好的对象,是后者的一个子集;而后者包括了一些在运行过程中动态创建的对象.

mysql java hibernate类型对应

- - 企业架构 - ITeye博客
类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述   . CHAR N CHAR java.lang.String 1  字符型  . BLOB L+N BLOB java.lang.byte[] -4  二进制型  . TEXT 65535 VARCHAR java.lang.String -1 text文本型  .