600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > oracle mysql查询速度慢_oracle 根据时间范围查询缓慢问题排查解决

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

时间:2021-11-23 16:14:51

相关推荐

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

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

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

select t.* from IMS_NTF_REMIND_HIS_11 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。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。