postgresql postgres:实体化视图的部分刷新?

k4emjkb1  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(2)|浏览(128)

我有这个物化视图:

Materialized view "public.kwh_tag"
   Column    |       Type       | Collation | Nullable | Default | Storage | Stats target | Description
-------------+------------------+-----------+----------+---------+---------+--------------+-------------
 timest      | date             |           |          |         | plain   |              |
 Zählerstand | double precision |           |          |         | plain   |              |
 kWh         | double precision |           |          |         | plain   |              |
Indexes:
    "kwh_tag_timest_idx" UNIQUE, btree (timest)
View definition:
 SELECT s.timest::date AS timest,
    s.kwh_180 AS "Zählerstand",
    s.kwh_180 - lag(s.kwh_180, 1) OVER (ORDER BY s.timest) AS "kWh"
   FROM ( SELECT DISTINCT ON ((smartmeter.timest::date)) smartmeter.timest,
            smartmeter.kwh_180
           FROM smartmeter
          ORDER BY (smartmeter.timest::date) DESC, smartmeter.timest DESC) s;

输出:

2023-06-10 |  35965.0285 | 22.8133000000016
 2023-06-11 |   35985.919 | 20.8905000000013
 2023-06-12 |  36012.7307 | 26.8116999999984
 2023-06-13 |  36030.2164 | 17.4856999999975

原因是,这个查询需要很多时间,因为表smartmeter每秒存储一次数据(如果设备需要更长的时间,则为2)。

REFRESH MATERIALIZED VIEW
Time: 94290.866 ms (01:34.291)

然而,每天刷新视图也需要更多的时间,有没有更好的方法来处理这个问题?
我尝试使用CONCURRENTLY,但这需要更长的时间,尽管只有一点点:

REFRESH MATERIALIZED VIEW CONCURRENTLY kwh_tag;
REFRESH MATERIALIZED VIEW
Time: 111461.192 ms (01:51.461)

理想情况下,只需要计算最近的一天,因为旧的值不会改变。我可以在postgres之外这样做,然后把它保存回来,但是一个in-postgres的解决方案会更好。

v2g6jxz6

v2g6jxz61#

这种情况的一个替代方案是将timescaledb扩展与continuous aggregates特性一起使用。
您可以创建一个仅在新数据中运行的连续聚合策略,因为它使用水印来了解最新运行的数据。

vxf3dgd4

vxf3dgd42#

您可以创建分区表,而不是实体化视图。每个分区用于特定时间范围内的值。每天,您都会使用TRUNCATEINSERT INTO ... SELECT ...来重建最新的分区。

相关问题