从状态更新表中有效获取具有给定状态的ID
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从状态更新表中有效获取具有给定状态的ID相关的知识,希望对你有一定的参考价值。
我有一个SQLite表,其中记录了具有列TaskID
,Timestamp
和Status
的状态更新的历史记录。每次任务状态更新时,我都会在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之外才能获得所需性能的地步?
相关:
答案
尝试使用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'
以上是关于从状态更新表中有效获取具有给定状态的ID的主要内容,如果未能解决你的问题,请参考以下文章
如何在表单正文中获取(orderId)有效负载值以更新订单状态?
如何从更新表中获取最新状态并将其与 MySQL 中的详细信息表连接?