diff --git a/scripts/sql/p1_historian.sql b/scripts/sql/p1_historian.sql index 8a9a89b..70ac2fb 100644 --- a/scripts/sql/p1_historian.sql +++ b/scripts/sql/p1_historian.sql @@ -20,3 +20,16 @@ SELECT add_compression_policy('hc900.history_1s', INTERVAL '6 hours', if_not_exi SELECT add_retention_policy('hc900.history_1s', INTERVAL '14 days', if_not_exists => TRUE); CREATE INDEX IF NOT EXISTS ix_h1s_tag ON hc900.history_1s (tagname, recorded_at DESC); + +-- P1b: 연속집계 history_1min — 1초 버퍼 evict 전 60초 롤업(장기 무손실, 2계층) +CREATE MATERIALIZED VIEW IF NOT EXISTS hc900.history_1min +WITH (timescaledb.continuous) AS +SELECT time_bucket('1 minute', recorded_at) AS bucket, tagname, + last(value, recorded_at) AS value, last(controller_id, recorded_at) AS controller_id +FROM hc900.history_1s GROUP BY bucket, tagname +WITH NO DATA; + +-- 집계 lag(≤3h) ≪ 보존 윈도(14일) → raw 삭제 전 materialize 보장 +SELECT add_continuous_aggregate_policy('hc900.history_1min', + start_offset => INTERVAL '3 hours', end_offset => INTERVAL '10 minutes', + schedule_interval => INTERVAL '5 minutes', if_not_exists => TRUE); diff --git a/src/Infrastructure/Hc900/Hc900FastHistoryService.cs b/src/Infrastructure/Hc900/Hc900FastHistoryService.cs index d931560..72007bb 100644 --- a/src/Infrastructure/Hc900/Hc900FastHistoryService.cs +++ b/src/Infrastructure/Hc900/Hc900FastHistoryService.cs @@ -90,6 +90,15 @@ WHERE tagname = ANY(@tags)"; "SELECT add_compression_policy('hc900.history_1s', INTERVAL '6 hours', if_not_exists => TRUE)", $"SELECT add_retention_policy('hc900.history_1s', INTERVAL '{_retentionDays} days', if_not_exists => TRUE)", "CREATE INDEX IF NOT EXISTS ix_h1s_tag ON hc900.history_1s (tagname, recorded_at DESC)", + // P1b: 연속집계 — 1초 버퍼 evict 전 60초 롤업(장기 무손실) + @"CREATE MATERIALIZED VIEW IF NOT EXISTS hc900.history_1min + WITH (timescaledb.continuous) AS + SELECT time_bucket('1 minute', recorded_at) AS bucket, tagname, + last(value, recorded_at) AS value, last(controller_id, recorded_at) AS controller_id + FROM hc900.history_1s GROUP BY bucket, tagname WITH NO DATA", + @"SELECT add_continuous_aggregate_policy('hc900.history_1min', + start_offset => INTERVAL '3 hours', end_offset => INTERVAL '10 minutes', + schedule_interval => INTERVAL '5 minutes', if_not_exists => TRUE)", }; foreach (var s in stmts) {