MySQL,在X个小时内返回所有测量值和结果

MySQL,在X个小时内返回所有测量值和结果,mysql,performance,join,Mysql,Performance,Join,这个问题与我的前一个问题非常相关:尽管有额外的重大限制: 现在我有两个表,一个用于测量,一个用于部分测量的分类结果 测量值不断到达,因此,在对新测量值进行分类后不断添加测量值 结果不一定按照测量的到达和存储顺序存储 我只想展示上次的结果。我的意思是取最后一个可用结果的最大时间(时间是测量结构的一部分),称之为Y,范围为X秒,并在Y和Y-X之间呈现测量值和可用的结果 以下是两个表的结构: 事件表: CREATE TABLE `event_data` ( `id` int(11) NOT NUL

这个问题与我的前一个问题非常相关:尽管有额外的重大限制:

现在我有两个表,一个用于测量,一个用于部分测量的分类结果

测量值不断到达,因此,在对新测量值进行分类后不断添加测量值

结果不一定按照测量的到达和存储顺序存储

我只想展示上次的结果。我的意思是取最后一个可用结果的最大时间(时间是测量结构的一部分),称之为Y,范围为X秒,并在Y和Y-X之间呈现测量值和可用的结果

以下是两个表的结构:

事件表:

CREATE TABLE `event_data` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `Feature` char(256) NOT NULL,
  `UnixTimeStamp` int(10) unsigned NOT NULL,
  `Value` double NOT NULL,

  KEY `ix_filter` (`Feature`),
  KEY `ix_time` (`UnixTimeStamp`),
  KEY `id_index` (`id`)
) ENGINE=MyISAM
分类结果表:

CREATE TABLE `event_results` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `level` enum('NORMAL','SUSPICIOUS') DEFAULT NULL,
  `score` double DEFAULT NULL,
  `eventId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `eventId_index` (`eventId`)
) ENGINE=MyISAM
我无法首先查询最后一次测量的时间戳,因为我想显示当前有结果的测量,并且由于测量不断到达,结果可能仍然不可用

因此,我考虑使用
event\u results.eventId=event\u data.id
,然后选择
event\u data.unixtimestap的最大时间作为maxTime
,在获得maxTime之后,我需要再次执行相同的操作(连接两个表)并在where子句中添加一个条件

其中event_data.UnixTimeStamp>=maxTime+INTERVAL-X秒


仅仅为了达到我的要求而执行2次联接似乎效率不高,根据我的理解,您是否有更多ef

,您正在使用聚合函数,
MAX
。这将产生一个大小为1的记录集,这是您将执行的最高时间。因此,需要将其分解为一个子查询(如您所说,嵌套选择)。您必须在某个时刻执行两个查询。(上一个问题的答案中有两个查询,通过子查询/嵌套选择)

子查询导致问题的主要时间是在查询的select部分执行子查询时,因为每次有行时它都会执行子查询,这将使查询的运行速度随着结果集的增长而呈指数级降低。让我们把你最后一个问题的答案用一种可怕、低效的方式写下来:

SELECT timeStart, 
       (SELECT max(timeStart) FROM events) AS maxTime
FROM events
WHERE   timeStart > (maxTime + INTERVAL -1 SECOND)
这将在每次有eventTime记录时执行select查询,查询最大eventTime。它应该会产生相同的结果,但这是缓慢的。这就是对子查询的恐惧之源

它还对每行执行聚合函数
MAX
,每次返回相同的答案。因此,您只需执行该子查询一次,而不是对每一行执行一次

但是,对于上一个问题的答案,
MAX
子查询部分将运行一次,并用于过滤where,其中选择将运行一次。因此,总共运行了2个查询


两个超快速查询比一个超慢速查询更快。我不完全确定您想要返回什么结果集,所以我将做一些假设。请随意更正我所做的任何假设

(对我来说)这听起来像是希望
event\u data
中的所有行都在绝对“最新”时间戳的一小时(或多少秒)内,如果有任何匹配行可用,您还希望与这些行一起返回
event\u results
中的任何相关行

如果是这样的话,那么使用内联视图来检索时间戳的最大值就是一种方法。(该操作将非常高效,因为查询将返回一行,并且可以从现有索引中高效地检索。)

由于您需要指定时间段内的所有行(从“最新时间”返回到“最新时间减去X秒”),因此我们可以继续在同一查询中计算该时间段的开始时间戳。这里我们假设您想“返回”一小时(=60*60秒):

注意:上面选择列表中的表达式基于定义为整数类型的
unixtimestap
列,而不是DATETIME或TIMESTAMP数据类型。如果该列被定义为DATETIME或TIMESTAMP数据类型,则我们可能会用如下方式表示:

SELECT MAX(mydatetime) + INTERVAL -3600 SECONDS
SELECT d.id
     , d.Feature
     , d.UnixTimeStamp
     , d.Value
  JOIN ( SELECT MAX(l.UnixTimeStamp) - 3600 AS from_unixtimestamp
           FROM event_data l
       ) m
  JOIN event_data d
    ON d.UnixTimetamp >= m.from_unixtimestamp
(我们可以以分钟、小时等为单位指定间隔单位)

我们可以在另一个查询中使用该查询的结果。要在同一查询文本中实现这一点,我们只需将该查询包装在括号中,并将其作为行源引用,就好像该查询是一个实际的表一样。这允许我们从
event\u data
中获取指定时间段内的所有行,如下所示:

SELECT MAX(mydatetime) + INTERVAL -3600 SECONDS
SELECT d.id
     , d.Feature
     , d.UnixTimeStamp
     , d.Value
  JOIN ( SELECT MAX(l.UnixTimeStamp) - 3600 AS from_unixtimestamp
           FROM event_data l
       ) m
  JOIN event_data d
    ON d.UnixTimetamp >= m.from_unixtimestamp
在这种特殊情况下,外部查询中的UnixTimeStamp列不需要上界谓词。这是因为我们已经知道没有任何UnixTimeStamp的值大于MAX(UnixTimeStamp),这是我们感兴趣的周期的上限


(我们可以在内联视图的选择列表中添加一个表达式,以返回
MAX(l.UnixTimeStamp)至于_unixtimestamp
,然后包括一个类似于
和d.unixtimestamp的谓词。问题是最大时间不能直接从事件_结果表中计算,我需要执行join以提取存在分类结果的事件的最大时间,这只是第一个查询,第二个查询将在ad中使用最大时间传统的联接查询,因此事实上我有两个查询执行相同的联接,这是非常糟糕的。两次联接到同一个表本身并没有什么问题;有时,这是返回指定结果集的最有效方法。不清楚结果集是什么样的…是否要返回所有行从
事件\u结果
表格