MySQL以日期时间间隔连接两个表

时间:2018-06-28 23:25:05

标签: mysql sql join

我正在开发一种类型的漫游器检测系统,该系统可以帮助我运行一些ML来识别这种流量。

长话短说,我有两个桌子:

  1. 一个表包含带有datetime列的所有服务器日志数据(向下到第二级的请求)
  2. 一个表,该表中有一行我已识别出的异常事件。 (带有日期时间列)

我需要做的是能够将表2与1结合起来,并在每次异常事件发生前1分钟和5分钟获得服务器请求的列表。

因此,我有两个表,想要在它们之间进行联接并总结服务器请求列。联接条件应该是表A的时间在表B的时间的1-5分钟之内。

所以B.time <= A.time <= B.time +(1 | 5)分钟

这是代码,我在两个datetime列上都有索引(btree)。但它似乎运行SUPER SLOW。我能做些别的事情吗?

该日志表有几百万行,而例外表大约有3,000。

SELECT
    a.Name AS ExceptionName,
    SUM(b.Requests) AS Requests1MBefore,
    SUM(c.Requests) AS Requests5MBefore,
FROM exceptions a
LEFT JOIN log b
ON
    b.Datet <= a.Datet
    and a.Datet <= DATE_ADD(b.Datet, INTERVAL 1 MINUTE)
LEFT JOIN log c
ON
    c.Datet <= a.Datet
    and a.Datet <= DATE_ADD(c.Datet, INTERVAL 5 MINUTE)
GROUP BY
    a.name

我希望输出是一个如下所示的联接表:

Exception Name | Requests1MBefore | Requests5MBefore
Event1         | 50               | 500
Event2         | 10               | 1000
....

2 个答案:

答案 0 :(得分:0)

这是一种方法:

SELECT e.Name AS ExceptionName,
       SUM( l.Datet > DATE_SUB(e.Datet, INTERVAL 1 MINUTE) as Requests1MinBefore,
       COUNT(l.Datet) as Requests5MinBefore
FROM exceptions e LEFT JOIN
     log l
     ON l.Datet <= e.Datet AND
        l.Datet > DATE_SUB(e.Datet, INTERVAL 5 MINUTE)
GROUP BY e.name;

答案 1 :(得分:0)

您的查询不可保存。在联接中或在有条件的情况下强制执行表扫描的列上使用函数。 我建议您在表 log 中创建2个生成/计算的列。一栏将存储实际时间之前1分钟的时间,另一栏将存储实际时间之前5分钟的时间。

此后,您可以使用这2个新列来联接表。您还可以为这2个新列建立索引,以使搜索更快。

但是,这种方法将增加表 log 中的插入成本。因此,您需要仔细考虑这种方法。

让我知道这是否有帮助。