Я бегу Postgres 9.2 и у меня есть большой стол что-то вродескользящее среднее Postgres
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 значений, поэтому я могу определить, находятся ли новые значения, входящие в систему, с тремя стандартными отклонениями среднего значения. Для этого мне понадобится текущее стандартное отклонение, и оно будет постоянно обновляться для последних 200 значений. Поскольку таблица может быть сотнями миллионов строк, я не хочу, чтобы последние сказали 200 строк для датчика, заказанного по времени, а затем выполнили vg (value), var_samp (значение) для каждого нового значения. I и предполагая он будет быстрее обновлять стандартное отклонение и среднее значение.
Я начал писать функцию 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 значений. Старое значение является первым значением окна. Когда приходит новое значение, мы сдвигаем окно вперед. После того, как я получаю результат я храню следующие значения для датчика
The first value of the window.
The mean average of the window values.
The variance of the window values.
Таким образом, я не должен постоянно получать там последние 200 значения и сделать сумму etc.I можно повторно использовать эти значения, когда новое значение датчика Заходите.
Моя проблема в первом запуске У меня нет данных предыдущего окна для датчика, т. е. трех значений выше, поэтому я должен сделать это медленным способом.
что-то вроде
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;
Но как я могу получить последнее значение (ealiest), чтобы спасти от этого оператора выбора? Могу ли я получить доступ к первой строке из s в PL/pgSQL.
Я думал, что PL/pgSQL будет более быстрым/чистым, но, возможно, лучше сделать это клиентский код? Есть ли лучшие способы выполнить этот тип при обновлении статистики?
насчет 'AVG (значение) над (перегородкой по sensor_id порядка Т.С. строк между 200 и предыдущей текущей строки) в качестве avg' –