持续聚集

1. 背景介绍

实际场景中,聚集查询十分常见,因为聚集查询一般基于较大数量级的基础数据集,并对其进行归纳分组聚合运算,所以通常被认为是一种耗时相对较高的查询种类,且多用于分析型的场景。另外,实际场景中对聚集查询的执行频率越来越频繁,同时对聚集查询的响应时间要求也越来越高。

持续聚集即是一种能快速响应聚集查询的机制。创建持续聚集后,在数据写入过程中,系统自动实时对原数据进行聚集计算,因为和原表数据事务级同步,建议用户尽可能直接查询持续聚集视图。

2. 使用方法

2.1 创建扩展

持续聚集依赖matrixts扩展,首先创建扩展:

CREATE EXTENSION matrixts;

2.2 创建数据表

数据表即原始数据表:

CREATE TABLE metrics(
    time timestamp,
    tag_id int,
    sensor float4
)
Distributed by(tag_id);

2.3 创建持续聚集视图

持续聚集使用物化视图来存储聚集后的结果,需要在创建视图时给出WITH (CONTINUOUS)关键字,和聚集语句:

CREATE VIEW cv1 WITH (CONTINUOUS) AS
    SELECT tag_id, COUNT(*), SUM(sensor)
    FROM metrics GROUP BY tag_id;

2.4 向源数据表插入数据

INSERT INTO metrics VALUES(NOW(), 1, 1.1);
INSERT INTO metrics VALUES(NOW(), 1, 1.2);
INSERT INTO metrics VALUES(NOW(), 2, 2.1);
INSERT INTO metrics VALUES(NOW(), 2, 2.2);

2.5 查询持续聚集视图

使用持续聚集时,只要向原始数据表插入时序数据,物化视图就会自动计算好结果:

SELECT * FROM cv1 ORDER BY tag_id;
 tag_id | count |    sum
--------+-------+-----------
      1 |     2 | 2.3000002
      2 |     2 |       4.3
(2 rows)

物化视图的结果与对原表进行聚合计算的结果相同:

SELECT tag_id, COUNT(*), SUM(sensor)
    FROM metrics
    GROUP BY tag_id
    ORDER BY tag_id;
 tag_id | count |    sum
--------+-------+-----------
      1 |     2 | 2.3000002
      2 |     2 |       4.3
(2 rows)

如果在创建持续聚集时源表已经有数据,默认也会将数据同步过来。如果不需要同步的话,在创建视图时需要将参数POPULATE手动设定为false(默认为true):

CREATE VIEW cv1 WITH (CONTINUOUS, POPULATE=false) AS
    SELECT tag_id, COUNT(*), SUM(sensor)
    FROM metrics GROUP BY tag_id;

3. 维护方法

MatrixDB提供了对持续聚集进行维护的UDF:

  • matrixts_internal.analyze_continuous_view(rel REGCLASS)

    ANALYZE物化视图,可以更新统计信息,有利于优化器做计算: SELECT matrixts_internal.analyze_continuous_view('cv1');

  • matrixts_internal.vacuum_continuous_view(rel REGCLASS, full BOOL)

    VACUUM物化视图,可以清理Dead tuple,使空间重复利用;第二个参数为true的话会重建表文件、减少存储空间: SELECT matrixts_internal.vacuum_continuous_view('cv1', true);

  • matrixts_internal.rebuild_continuous_view(rel REGCLASS)

    重建物化视图,适用于源数据表做了更新删除,重新全量同步数据的场景: SELECT matrixts_internal.rebuild_continuous_view('cv1');

4. FAQ

  1. 物化视图的数据与源表是实时同步的吗?
    • 是的,源表插入数据提交后,即可从物化视图查询到
  2. 持续聚集可以保证ACID吗?
    • 可以的,物化视图中的数据与原表数据使用相同的事务ID
  3. 如何处理更新删除?
    • 原表的更新删除以及DROP并不会体现在持续聚集视图中,但支持upsert更新和非空最新值last_not_null聚合
  4. 持续聚集对窗口函数有效吗?
    • 暂不支持窗口函数
  5. 持续聚集是否支持partition表?
    • 支持
  6. 持续聚集支持多表聚集吗?
    • 不支持
  7. 一张表可以定义多个持续聚集吗?
    • 可以