MySQL 查询性能与日期范围和时间步长

Posted

技术标签:

【中文标题】MySQL 查询性能与日期范围和时间步长【英文标题】:MySQL Query Performance with Date Range and Time Step 【发布时间】:2016-12-22 22:16:57 【问题描述】:

我有一个包含以下列的表格:incident_idcreation_dateevent_idsignature_id

而这个子程序(简化版)查询表:

while time1 < end_date and time2 < end_date do
  stmt = "SELECT incident_id, COUNT(event_id) AS total
       FROM table
       WHERE creation_date BETWEEN #time1 AND #time2
         AND signature_id IN (29476,9935,16353,35726,40340,45471,36047,
                              105630,105730,73274)
       GROUP BY signature_id "
  results = db_connect.fetch_all(stmt)
  foreach result in results do
     ... some post processing ...
  end 
  time1 = time1 + time_step
  time2 = time2 + time_step
end

这样做的问题是列没有索引并且行数很大,所以现在性能真的很差。有没有办法在不获取循环内结果的情况下进行查询?

更新:我认为我应该先预先计算循环中的时间范围,然后在 SQL 查询中对所有这些时间范围进行 OR。唯一的问题是 COUNT(event_id),我不知道如何计算每个时间范围。

【问题讨论】:

【参考方案1】:

添加这个复合索引:

INDEX(signature_id, creation_date)

您可以在一个查询中收集所有数据。那是你要找的吗?如果是这样,那么你需要类似的东西

GROUP BY signature_id, some_function(creation_date)

some_function 背后的想法是花时间,除以 time_step,然后将其用于分组。如果是简单的东西,比如DAY,那么LEFT(creation_date, 10)DATE(creation_date) 很简单。否则,请详细说明您的用例。

【讨论】:

这个问题提到了完全缺乏索引,尽管如此推测 OP 至少知道添加索引应该有所帮助,但由于其他原因没有这样做。 基于此,我假设他们实际上是在寻找类似archiving 的东西,或者首先将新行放入一些“未处理”表中。可以选择在视图中组合这两个表以使其看起来无缝(但我对它们的情况了解不足,无法将其形成完整的答案)。 @LukeBriggs - 随时根据您的想法提供答案。 不能使用索引,是公司的问题,他们想优化这个而不做那个。 预热你的简历。如果公司不让你做你的工作,但对索引有一些蹩脚的论据,那就离开吧!

以上是关于MySQL 查询性能与日期范围和时间步长的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 用 BETWEEN AND 日期查询包含范围边界

MySQL 用 BETWEEN AND 日期查询包含范围边界

这些查询 MySQL 日期范围之间有啥区别

Mysql查询 - 返回两个日期范围相交的日期

我如何查询给定日期范围的mysql并加入两个表?

使用未在 Mysql 中排序的多个日期范围查询给定月份的日期范围间隙