0

我做了一个选择 的查询last secods,例如:如果现在是 10:30:30s 并且我传递了last 20 seconds它应该只返回和之间的值10:30:1010:30:30所以这里是:

    public List<Log> listLastSeconds(Integer id_point, int seconds) {
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.SECOND, -seconds);

    Date today = new Date();
    Date lastSeconds = calendar.getTime();

     Query query = em.createQuery("SELECT l FROM Log l WHERE l.point.id =:id AND l.time >= :lastSeconds AND l.time <= :today", Log.class);
     query.setParameter("id", id_point);
     query.setParameter("lastSeconds", lastSeconds);
     query.setParameter("today", today);

     return query.getResultList();
}

但是即使对于很小的差异(例如 10 秒),此查询也需要很长时间。

编辑:

CREATE TABLE `log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_point` int(11) NOT NULL,
  `value` varchar(10) NOT NULL,
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `fk_point_id` (`id_point`),
  CONSTRAINT `fk_point_id` FOREIGN KEY (`id_point`) REFERENCES `point` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=9360244 DEFAULT CHARSET=latin2$$

如何改进此查询以更快?

4

2 回答 2

1

您需要在列上建立索引time。这将做到:

CREATE INDEX time_index using btree on log(time);
于 2012-04-06T13:58:33.417 回答
0

我会用DATE_ADD. 首先去掉todaylastSeconds变量;使用此查询并将方法参数设置为查询的参数。

SELECT l 
FROM Log l 
WHERE l.point.id =:id
AND l.time >= DATE_ADD(CURTIME(), INTERVAL :seconds SECOND)

我很想测试它,但目前没有 mysql 访问权限。将尽快对其进行测试:)

然而,这可能不会提供很大的性能提升,因为它仍然会搜索整个表。

如果您对正在处理的数据的性质有所了解,例如在过去 10 秒内可能添加的最大行数是多少,那么您可以添加一个子句,说明表 id 大于 max( id) - N,这只是举例,任何其他可以限制搜索空间并具有商业意义的指标都会为您提供真正的性能提升。

时间列上的索引是一种选择,但我不太熟悉它的实用性或速度如何?有人对使用索引有意见吗?

于 2012-04-06T16:23:26.227 回答