在来自多个传感器的定时观察表中,如何以最佳方式检索每个传感器的最后一次观察

Posted

技术标签:

【中文标题】在来自多个传感器的定时观察表中,如何以最佳方式检索每个传感器的最后一次观察【英文标题】:In a table of timed observations from multiple sensors, how to optimally retrieve the last observation for each sensor 【发布时间】:2021-04-14 14:36:57 【问题描述】:

我的表格如下:

sensor time value
AAA 2021-01-05 04:10:14 3.14159
AAA 2021-01-05 05:08:07 3.94756
ABC 2021-01-05 03:40:54 4.32543

我正在寻找一个查询来检索与每个传感器的最后一次观察相对应的行,即:

sensor time value
AAA 2021-01-05 05:08:07 3.94756
ABC 2021-01-05 03:40:54 4.32543

在做了一些研究后,我发现了这个解决方案:

SELECT DISTINCT ON (sensor) sensor, time, value
FROM observations
ORDER BY sensor, time DESC

上面的问题是对于大表来说成本相当高。

一种可能的解决方案是让另一个表只保存每个传感器的最后一次观察,与保存所有历史记录的表分开。虽然这样可行,但我想知道是否有更优雅的东西,即允许我保留一个表,同时具有更好的性能。

提前致谢。

【问题讨论】:

distinct on() 通常是最有效的方法。 【参考方案1】:

可以使用ROW_NUMBER()等窗口函数

SELECT sensor, time, value
 FROM
 (
  SELECT o.*,
         ROW_NUMBER() OVER (PARTITION BY sensor ORDER BY time DESC) AS rn
    FROM observations o ) oo
 WHERE rn = 1

假设时间值出现平局,则可以使用DENSE_RANK() 函数代替,以便在结果集中包含所有相等的时间值。

Demo

【讨论】:

distinct on () 通常比窗口函数更有效【参考方案2】:

您可以尝试使用递归 CTE:

with recursive t as (
    (select sensor, time, value
     from observations
     order by sensor, time desc limit 1)
    union all
    (select o.sensor, o.time, o.value
     from observations as o join t on (o.sensor > t.sensor)
     order by o.sensor, o.time desc limit 1))
select * from t;

observations(sensor, time desc) 上的索引可能会有很大帮助。

【讨论】:

【参考方案3】:

对于这个查询:

SELECT DISTINCT ON (sensor) sensor, time, value
FROM observations
ORDER BY sensor, time DESC

您希望在(sensor, time desc) 上建立索引。

有了这样的索引,这可能是做你想做的最快的方法。

【讨论】:

以上是关于在来自多个传感器的定时观察表中,如何以最佳方式检索每个传感器的最后一次观察的主要内容,如果未能解决你的问题,请参考以下文章

最佳方式以及如何在 mac osx 可可应用程序中显示多个视图?

如何在全球范围内以最佳方式处理来自服务器的 401/403 响应

如何从多个聚合表中检索数据?

包含来自多个源表的数据的维度中自然键的最佳实践

创建最佳查询以查找仅在一个表中的记录

在 sql server 中存储和检索评论回复的最佳方式