gpt4 book ai didi

sql - 滚动平均postgres

转载 作者:行者123 更新时间:2023-11-29 11:30:15 25 4
gpt4 key购买 nike

我正在运行 Postgres 9.2,我有一个大 table ,类似

CREATE TABLE sensor_values
(
ts timestamp with time zone NOT NULL,
value double precision NOT NULL DEFAULT 'NaN'::real,
sensor_id integer NOT NULL
)

我有值不断地进入系统,即每分钟很多。我想为最后 200 个值保持滚动标准偏差/平均值,这样我就可以确定进入系统的新值是否在平均值的 3 个标准偏差范围内。为此,我需要当前的标准差,并且意味着要不断更新最近 200 个值。由于该表可能有数亿行,所以我不想为按时间排序的传感器获取最后说的 200 行,然后为每个进来的新值执行 vg(value)、var_samp(value)。我假设它更新标准偏差和平均值会更快。

我已经开始编写一个 PL/pgSQL 函数来更新滚动方差,并针对特定传感器进入系统的每个新值进行平均。

我可以使用伪代码来做到这一点

newavg = oldavg + (new_value - old_value)/window_size
new_variance += (new_value-old_value)*(new_value-newavg+old_value-oldavg)/(window_size-1)

这是基于 http://jonisalonen.com/2014/efficient-and-accurate-rolling-standard-deviation/

基本上,窗口的大小为 200 个值。 old_value 是窗口的第一个值。当一个新值进来时,我们将窗口向前移动一个。得到结果后,我为传感器存储以下值

The first value of the window.
The mean average of the window values.
The variance of the window values.

这样我就不必经常获取最后 200 个值并进行求和等操作。当有新的传感器值出现时,我可以重复使用这些值。

我的问题是第一次运行时我没有传感器的先前窗口数据,即上面的三个值,所以我必须以缓慢的方式进行。

有点像

WITH s AS
(SELECT value FROM sensor_values WHERE sensor_values.sensor_id = $1 AND ts >= (NOW() - INTERVAL '2 day')::timestamptz ORDER BY ts DESC LIMIT 200)
SELECT avg(value), var_samp(value) INTO last_window_average, last_window_variance FROM s;

但是我怎样才能从该 select 语句中获取要保存的最后一个值(最早)?我可以在 PL/pgSQL 中从 s 访问第一行吗?

我认为 PL/pgSQL 会是更快/更清洁的方法,但也许更好的做法是使用客户端代码?有没有更好的方法来执行这种类型的滚动统计更新?

最佳答案

我假设,每次使用适当的索引重新计算最新的 200 个条目不会非常慢。如果你要做一个索引,比如:

CREATE INDEX i_sensor_values ON sensor_values(sensor_id, ts DESC);

您将能够相当快地获得结果:

SELECT sum("value") -- add more expressions as required
FROM sensor_values
WHERE sensor_id=$1
ORDER BY ts DESC
LIMIT 200;

您可以从 PL/pgSQL 函数循环执行此查询。如果您很快迁移到 9.3(或更高版本),您还可以使用 LATERAL joins为此目的。

我认为覆盖索引在这里不会有什么用,因为表在不断变化,IndexOnlyScan 不会启动。

检查一下就好了Loose Index scans还有。

附言列名 value 应该用双引号引起来,因为这是一个 SQL reserved word .

关于sql - 滚动平均postgres,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29819010/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com