【问题标题】:hacking to achieve (continuous aggregate) CAGG on top of CAGG on timescaleDB postgresql在 timescaleDB postgresql 上的 CAGG 之上实现(连续聚合)CAGG
【发布时间】:2021-11-07 21:07:29
【问题描述】:

只是想跟进这个话题https://github.com/timescale/timescaledb/issues/1400,是否可以在另一个连续聚合之上创建一个连续聚合? (通过执行一些黑客行为?)

我打算将刻度数据插入数据库(可能每 0.1 秒),并在 1 秒、1 分钟、1 小时、1 天、1 个月、1 年、10 年执行连续聚合。根据我目前对 CAGG 的理解,从时间上讲,10 年执行聚合将比 1 秒的 CAGG 花费约 3600* 24* 365* 10 倍,但是如果我们在 CAGG 之上进行 CAGG(通过创建新的超表来跟踪更改进行黑客攻击之前的物化视图),我们可能会以指数方式加速......

我的想法有效吗?由于我之前没有在 postgresql 上编写过任何触发函数...

【问题讨论】:

  • 目前不支持它,尽管有一个功能请求允许这个,如果你想看到它的优先级,你可以投票。请参阅github.com/timescale/timescaledb/issues/1400,那里也有一些关于工作区的讨论。
  • 我建议只创建最多一天的聚合,然后在查询时重新聚合连续聚合以获得结果。这并不适用于所有聚合,但是,添加 3650 个值仍然会非常快,从 0.1 秒到每天的聚合将为您带来大部分好处。

标签: postgresql timescaledb


【解决方案1】:

这是一个简单的原型,您可以自己破解它来提供第二个超表,例如在另一个超表之上提供连续聚合:

-- DROP TABLE ticks CASCADE;
-- DROP TABLE ohlc_1s CASCADE;
CREATE TABLE ticks ( time TIMESTAMP NOT NULL, symbol varchar, price decimal, volume int);
CREATE TABLE ohlc_1s ( time TIMESTAMP NOT NULL, symbol varchar, o decimal, h decimal, l decimal, c decimal, v int);
SELECT create_hypertable('ticks', 'time');
SELECT create_hypertable('ohlc_1s', 'time');

您还可以使用触发器来提供 ohlc_1s 表:

CREATE OR REPLACE FUNCTION feed_ohlc_1s() RETURNS trigger AS
$BODY$
DECLARE
    last_time timestamp;
BEGIN
   SELECT time_bucket('1 second', time) INTO last_time
   FROM ticks WHERE symbol = NEW.symbol
   ORDER BY time DESC LIMIT 1;

   -- When turn next second
   IF NEW.time - last_time >= INTERVAL '1 second' THEN
      INSERT INTO ohlc_1s (time, symbol, o, h, l, c, v)
        SELECT time_bucket('1 second', time) as time,
          symbol,
          FIRST(price, time) as open,
          MAX(price) as high,
          MIN(price) as low,
          LAST(price, time) as close,
          SUM(volume) as volume FROM ticks
        GROUP BY 1, 2 ORDER BY 1 DESC LIMIT 1;
  END IF;
  RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;

CREATE TRIGGER feed_ohlc_every_new_second
               BEFORE INSERT
               ON ticks
               FOR EACH ROW
               EXECUTE PROCEDURE feed_ohlc_1s();

这里我们举一些插入的例子:

INSERT INTO ticks VALUES 
('2021-08-26 10:09:00.01'::timestamp, 'SYMBOL', 10.1, 100),
('2021-08-26 10:09:00.08'::timestamp, 'SYMBOL', 10.0, 100),
('2021-08-26 10:09:00.23'::timestamp, 'SYMBOL', 10.2, 100),
('2021-08-26 10:09:00.40'::timestamp, 'SYMBOL', 10.3, 100);
table ticks;
table ohlc_1s;

正如您在同一秒内看到的,它不会生成任何新数据:

┌────────────────────────┬────────┬───────┬────────┐
│          time          │ symbol │ price │ volume │
├────────────────────────┼────────┼───────┼────────┤
│ 2021-08-26 10:09:00.01 │ SYMBOL │  10.1 │    100 │
│ 2021-08-26 10:09:00.08 │ SYMBOL │  10.0 │    100 │
│ 2021-08-26 10:09:00.23 │ SYMBOL │  10.2 │    100 │
│ 2021-08-26 10:09:00.4  │ SYMBOL │  10.3 │    100 │
└────────────────────────┴────────┴───────┴────────┘
(4 rows)

┌──────┬────────┬───┬───┬───┬───┬───┐
│ time │ symbol │ o │ h │ l │ c │ v │
├──────┼────────┼───┼───┼───┼───┼───┤
└──────┴────────┴───┴───┴───┴───┴───┘
(0 rows)

现在插入更多 2 秒的滴答声:

INSERT INTO ticks VALUES 
('2021-08-26 10:09:01.02'::timestamp, 'SYMBOL', 10.0, 100),
('2021-08-26 10:09:01.04'::timestamp, 'SYMBOL', 14.0, 200),
('2021-08-26 10:09:01.42'::timestamp, 'SYMBOL', 12.3, 200),
('2021-08-26 10:09:01.62'::timestamp, 'SYMBOL', 8.3, 200),
('2021-08-26 10:09:02.80'::timestamp, 'SYMBOL', 9.0, 500);
table ticks;
table ohlc_1s;

这是输出:

┌────────────────────────┬────────┬───────┬────────┐
│          time          │ symbol │ price │ volume │
├────────────────────────┼────────┼───────┼────────┤
│ 2021-08-26 10:09:00.01 │ SYMBOL │  10.1 │    100 │
│ 2021-08-26 10:09:00.08 │ SYMBOL │  10.0 │    100 │
│ 2021-08-26 10:09:00.23 │ SYMBOL │  10.2 │    100 │
│ 2021-08-26 10:09:00.4  │ SYMBOL │  10.3 │    100 │
│ 2021-08-26 10:09:01.02 │ SYMBOL │  10.0 │    100 │
│ 2021-08-26 10:09:01.04 │ SYMBOL │  14.0 │    200 │
│ 2021-08-26 10:09:01.42 │ SYMBOL │  12.3 │    200 │
│ 2021-08-26 10:09:01.62 │ SYMBOL │   8.3 │    200 │
│ 2021-08-26 10:09:02.8  │ SYMBOL │   9.0 │    500 │
└────────────────────────┴────────┴───────┴────────┘
(9 rows)

┌─────────────────────┬────────┬──────┬──────┬──────┬──────┬─────┐
│        time         │ symbol │  o   │  h   │  l   │  c   │  v  │
├─────────────────────┼────────┼──────┼──────┼──────┼──────┼─────┤
│ 2021-08-26 10:09:00 │ SYMBOL │ 10.1 │ 10.3 │ 10.0 │ 10.3 │ 400 │
│ 2021-08-26 10:09:01 │ SYMBOL │ 10.0 │ 14.0 │  8.3 │  8.3 │ 700 │
└─────────────────────┴────────┴──────┴──────┴──────┴──────┴─────┘
(2 rows)

可能将其链接到更大的时间范围也会使其非常简单。

【讨论】:

    猜你喜欢
    • 2021-10-29
    • 1970-01-01
    • 2021-04-26
    • 2020-12-31
    • 2021-11-21
    • 2021-10-03
    • 1970-01-01
    • 2020-12-20
    • 2022-08-21
    相关资源
    最近更新 更多