实时聚合不是最新的

Pas*_*wig 6 real-time-data timescaledb continuous-aggregates

我正在经历实时聚合而不是实时更新。我有什么遗漏的吗?

2.4.2使用当前 docker 镜像的版本的可重现示例timescale/timescaledb:latest-pg12

CREATE TABLE data
(
    time  TIMESTAMPTZ      NOT NULL,
    value DOUBLE PRECISION NOT NULL
);

SELECT create_hypertable('data', 'time', chunk_time_interval => interval '1d');

INSERT INTO data (time, value)
VALUES ('2020-01-01', 100);

CREATE MATERIALIZED VIEW data_daily WITH (timescaledb.continuous)
AS
SELECT time_bucket('1 day', time) AS time,
       avg(value)                 AS avg,
       count(*)                   AS count
FROM data
GROUP BY 1;
ALTER MATERIALIZED VIEW data_daily SET (timescaledb.materialized_only = false);
Run Code Online (Sandbox Code Playgroud)

现在,当我运行时,SELECT * FROM data_daily我得到了预期的结果:

time, avg, count
2020-01-01 00:00:00.000000, 100, 1
Run Code Online (Sandbox Code Playgroud)

但是插入另一个值并再次运行查询后,它不会更新。结果与上面相同。

time, avg, count
2020-01-01 00:00:00.000000, 100, 1
Run Code Online (Sandbox Code Playgroud)

输出:

time, avg, count
2020-01-01 00:00:00.000000, 100, 1
Run Code Online (Sandbox Code Playgroud)

手动刷新然后再次查询就会显示预期的结果。

INSERT INTO data (time, value) VALUES ('2020-01-01', 150);

SELECT * FROM data_daily;
Run Code Online (Sandbox Code Playgroud)

输出:

time, avg, count
2020-01-01 00:00:00.000000, 125, 2
Run Code Online (Sandbox Code Playgroud)

是否还需要配置其他任何内容才能使实时聚合发挥作用?从文档中我了解到设置materialized_only = false应该足够了(甚至没有必要,因为它是默认设置)。

作为参考,这是第二次插入之后、手动刷新之前的查询计划:

 Append  (cost=0.15..59.98 rows=400 width=24) (actual time=0.138..0.200 rows=1 loops=1)
   ->  GroupAggregate  (cost=0.15..21.76 rows=200 width=24) (actual time=0.130..0.151 rows=1 loops=1)
         Group Key: _materialized_hypertable_48."time"
         ->  Custom Scan (ChunkAppend) on _materialized_hypertable_48  (cost=0.15..16.81 rows=260 width=72) (actual time=0.021..0.046 rows=1 loops=1)
               Order: _materialized_hypertable_48."time"
               Chunks excluded during startup: 0
               ->  Index Scan Backward using _hyper_48_315_chunk__materialized_hypertable_48_time_idx on _hyper_48_315_chunk  (cost=0.15..16.81 rows=260 width=72) (actual time=0.014..0.023 rows=1 loops=1)
                     Index Cond: ("time" < COALESCE(_timescaledb_internal.to_timestamp(_timescaledb_internal.cagg_watermark(48)), '-infinity'::timestamp with time zone))
   ->  GroupAggregate  (cost=0.16..32.23 rows=200 width=24) (actual time=0.010..0.021 rows=0 loops=1)
         Group Key: (time_bucket('1 day'::interval, data."time"))
         ->  Custom Scan (ChunkAppend) on data  (cost=0.16..24.60 rows=617 width=16) (actual time=0.003..0.007 rows=0 loops=1)
               Order: time_bucket('1 day'::interval, data."time")
               Chunks excluded during startup: 1
 Planning Time: 4.978 ms
 Execution Time: 0.384 ms
Run Code Online (Sandbox Code Playgroud)

dav*_*idk 5

这是一个很好的问题,连续聚合的工作方式绝对有点令人困惑。

实时视图仅适用于尚未具体化的视图区域,不适用于已具体化但现已失效的区域。这是出于性能可预测性的原因以及物化和失效的工作方式。通常,刷新窗口会在小于 的某个时间调用now(),比如说now() - '1 hour'::interval从 1 小时前开始进行插入,然后实时视图将直接在该区域的基础表上运行查询now()-'1 hour'->now()并返回物化部分的结果之前的地区。可能有很多小区域已失效,因此这些区域只会在下次运行物化作业时被拾取。您可以说这是数据的最终一致视图。

现在对你来说,我想说最重要的是不要在太远的将来运行刷新过程,而是坚持过去,然后你会看到实时视图更像你期望的那样工作。