You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL(TimeScaleDB):高效合并两个统计视图的优化问询

燃气采暖设备时序数据按月聚合优化方案咨询

我将燃气采暖设备的监测数据存储在PostgreSQL数据库中,采用TimeScaleDB处理时序数据,需按月聚合采暖/热水燃烧占比、燃烧时长、燃气消耗等指标用于可视化分析。

目前通过三个视图实现统计:

1. 采暖与热水燃烧时长占比视图 v_heizung_ww_hz

按月统计采暖与热水的燃烧时长占比,视图定义如下:

View "public.v_heizung_ww_hz"
 Column |           Type           | Collation | Nullable | Default | Storage | Description
--------+--------------------------+-----------+----------+---------+---------+-------------
 time   | timestamp with time zone |           |          |         | plain   |
 ww     | double precision         |           |          |         | plain   |
 hz     | double precision         |           |          |         | plain   |
View definition:
 SELECT date_trunc('month'::text, heizung.timest) AS "time",
    sum(
        CASE
            WHEN heizung.ventil = 3 THEN heizung.brenner_status::integer
            ELSE 0
        END)::double precision / sum(heizung.brenner_status)::double precision AS ww,
    sum(
        CASE
            WHEN heizung.ventil = 1 THEN heizung.brenner_status::integer
            ELSE 0
        END)::double precision / sum(heizung.brenner_status)::double precision AS hz
   FROM heizung
  GROUP BY (date_trunc('month'::text, heizung.timest));

2. 日统计视图 v_heizung_daily

用于计算每日燃烧时长和启动次数,视图定义如下:

View "public.v_heizung_daily"
 Column  |       Type       | Collation | Nullable | Default | Storage | Description
---------+------------------+-----------+----------+---------+---------+-------------
 time    | date             |           |          |         | plain   |
 stunden | double precision |           |          |         | plain   |
 starts  | double precision |           |          |         | plain   |
View definition:
 SELECT s.timest::date AS "time",
    s.brenner_stunden::double precision - lag(s.brenner_stunden::double precision, 1) OVER (ORDER BY s.timest) AS stunden,
    s.brenner_starts::double precision - lag(s.brenner_starts::double precision, 1) OVER (ORDER BY s.timest) AS starts
   FROM ( SELECT DISTINCT ON ((heizung.timest::date)) heizung.timest,
            heizung.brenner_stunden,
            heizung.brenner_starts
           FROM heizung
          ORDER BY (heizung.timest::date) DESC, heizung.timest DESC) s;

3. 月度燃烧时长与燃气消耗视图 v_heizung_monthly

基于日统计视图按月聚合燃烧时长、燃气消耗,视图定义如下:

View "public.v_heizung_monthly"
 Column  |           Type           | Collation | Nullable | Default | Storage | Description
---------+--------------------------+-----------+----------+---------+---------+-------------
 time    | timestamp with time zone |           |          |         | plain   |
 stunden | double precision         |           |          |         | plain   |
 Gas %   | double precision         |           |          |         | plain   |
 Gas l   | double precision         |           |          |         | plain   |
View definition:
 SELECT date_trunc('month'::text, v_heizung_daily."time"::timestamp with time zone) AS "time",
    sum(v_heizung_daily.stunden) AS stunden,
    sum(v_heizung_daily.stunden) * 0.65::double precision / 50::double precision AS "Gas %",
    sum(v_heizung_daily.stunden) * 0.65::double precision AS "Gas l"
   FROM v_heizung_daily
  GROUP BY (date_trunc('month'::text, v_heizung_daily."time"::timestamp with time zone))
  ORDER BY (date_trunc('month'::text, v_heizung_daily."time"::timestamp with time zone));

性能瓶颈

当执行以下JOIN语句合并两个月度视图时,查询耗时长达1546.846ms:

select a.time, stunden, stunden*0.65*7 as "kWh", ww, hz, "Gas %", "Gas l", "Gas l"*ww as "ww_l", "Gas l"*hz as "hz_l" from v_heizung_ww_hz a join v_heizung_monthly b on a.time = b.time;

希望能找到更高效的实现方案,或者咨询是否应该使用物化视图来优化查询性能。

内容的提问来源于stack exchange,提问作者fsp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 13:25:18