oracle mysql查询速度慢_oracle 根据时间范围查询缓慢问题排查解决

今天生产环境上碰到个奇怪问题,在oracle数据库一个根据时间范围的查询语句居然执行了二十多分钟。一开始打印了执行sql日志之后就毫无反应了,任何错误都没有。把进程反复重启几次也一样。直到二十分钟后就出现了数据业务处理日志。表的数据量是千万级别,但是时间字段也加了索引的,不至于这么慢吧。查询的时间范围区间也就一分钟。

实在想不出原因在哪里,就写个简单的查询语句试试:

select t.* from IMS_NTF_REMIND_HIS_201711 t where t.SO_DATE>(sysdate-1/24/60) AND t.SO_DATE

奇迹发生,这个查询语句瞬间就出结果。马上查代码看查询语句怎么写的。

String sql = "select t.* from " + tableName + " t where " + " t.SO_DATE >=? and t.SO_DATE < ?";

if (logger.isDebugEnabled()) {

logger.debug("执行query的SQL:{}" , sql);

}

conn = ServiceManager.getSession().getConnection(dbAct);

prepare = conn.prepareStatement(sql);

prepare.setTimestamp(1, startTime);

prepare.setTimestamp(2, endTime);

从这个来看貌似也没发现什么问题,两条sql也没有什么区别。看一下数据库SO_DATE字段是date类型。至于为什么使用PreparedStatement.setTimestamp,是因为PreparedStatement.setDate();方法参数java.sql.Date的日期是没有时分秒的,

不符合查询要求。这里想说明一点,oracle数据库字段是date类型的,普通jdbc查询出来的是不带时分秒的,java.util.Date才带时分秒。要有时分秒就要做个转换

HashMap map = new HashMap();

ResultSetMetaData metaData = rs.getMetaData();

int columns = metaData.getColumnCount();

for (int i = 1; i <= columns; i++) {

if ("DATE".equals(metaData.getColumnTypeName(i))) {

map.put(metaData.getColumnName(i), rs.getTimestamp(i));

} else {

map.put(metaData.getColumnName(i), rs.getObject(i));

}

}

rtn.add(map);

言归正传,看到这里估计也猜出来了,oracle字段类型的隐式转换,将date类型转换为timestamp类型。导致索引失效,就会全表扫描,从而查询缓慢。知道问题所在解决就简单了,时间字符串,使用to_date()函数来转换字符串为日期和date做比较。改完之后重新测试查询速度变为了毫秒级别。

总结:

oracle date 和 timestamp类型混用时需要注意索引失效问题。如果oracle数据库字段是date类型,需要时分秒的就用字符串时间格式,使用to_date()函数转换做比较。不需要时分秒的就用java.sql.Date。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值