从状态更新表中有效获取具有给定状态的ID

问题描述 投票:1回答:1

我有一个SQLite表,其中记录了具有列TaskIDTimestampStatus的状态更新的历史记录。每次任务状态更新时,我都会在history表中添加一行描述新状态。任务的当前状态定义为与给定TaskID匹配的所有行中时间戳最大(最新)的行的Status值。当表达到约25,000行时,我遇到了问题。

我需要一些帮助,以有效地检索状态为“未开始”的单个任务。从概念上讲,该表如下所示:

TaskID   Status          Timestamp
------   -------------   ---------
1        "not started"   1
2        "not started"   2
2        "started"       3
1        "started"       4
1        "error"         5
1        "not started"   6

而且我想将任务1标识为当前状态为“未开始”的任务。

我已经尝试过

SELECT TaskID, h.Status
     FROM history AS h
     WHERE Timestamp = (SELECT MAX(Timestamp)
         FROM history as h2
         WHERE h2.TaskID = h.TaskID)
         AND h.Status = "not started"
     LIMIT 1

确实会检索正确的行,但是大约需要5秒钟。理想情况下,我希望查询时间低于1秒。

我一直在读GROUP BY ... HAVING作为化合物SELECT的替代品(我在瓶颈处猜测),但不能完全弄清楚如何首先为每个任务选择最新的行,然后过滤掉那些不行的行。不符合我在Status上的条件。

因此,是否有更好的方法来指定此查询?添加索引会有帮助吗?该表是否有更好的结构?还是我已经达到需要升级到SQLite之外才能获得所需性能的地步?

相关:

performance sqlite greatest-n-per-group
1个回答
0
投票

尝试使用ROW_NUMBER()窗口功能:

select t.TaskID, t.Status, t.Timestamp
from (
  select *,
    row_number() over (partition by TaskID order by Timestamp desc) rn
  from history  
) t  
where t.rn = 1 and t.Status = 'not started'
© www.soinside.com 2019 - 2024. All rights reserved.