【问题标题】:MySQL join two tables with datetime intervalMySQL以日期时间间隔连接两个表
【发布时间】:2018-06-28 23:25:04
【问题描述】:

我正在开发一种机器人检测系统,它可以帮助我运行一些机器学习来识别这种流量。

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

  1. 一个表包含所有服务器日志数据(向下至第二级的请求)和一个日期时间列
  2. 一个表有一行用于我发现的异常事件。 (带有日期时间列)

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

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

所以 B.time

这是代码,我在两个日期时间列上都有索引(btree)。但它似乎运行超慢。有什么我可以做的不一样的吗?

日志表有几百万行,异常表大约有 3000 行。

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
....

【问题讨论】:

  • 只做一个 JOIN 5 分钟,对 1 分钟列使用条件聚合。

标签: mysql sql join


【解决方案1】:

这是一种方法:

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;

【讨论】:

    【解决方案2】:

    您的查询不是 SARGable。在 join 中的列上使用函数或在 where 条件下强制执行表扫描。 我建议您应该在表 log 中创建 2 个生成/计算的列。一列将存储实际时间前 1 分钟的时间,另一列将存储实际时间前 5 分钟的时间。

    在此之后,您可以使用这 2 个新列来加入表格。您还可以索引这 2 个新列以加快搜索速度。

    不过,这种方法会增加插入表log的成本。所以你需要仔细考虑这种方法。

    如果这有帮助,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2015-08-06
      • 1970-01-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多