AnalyticDB PostgreSQL版提供了实时物化视图功能,相较于普通(非实时)物化视图,实时物化视图无需手动调用刷新命令,即可实现数据更新时自动同步刷新物化视图。

当基表发生变化时,构建在基表上的实时物化视图将会自动更新。您还可以在实时物化视图上再创建实时物化视图,当基表发生变化时,相关级联的实时物化视图也会自动更新。

目前AnalyticDB PostgreSQL版的实时物化视图仅支持语句(STATEMENT)级别的自动更新,即当基表的INSERT、COPY、UPDATE、DELETE语句执行成功时,构建于基表之上的物化视图都会实时更新,保证数据强一致。

说明 该模式下会对基表的写入性能会有一定影响,建议您不要在同一张基表上创建过多的实时物化视图。

普通物化视图的详细信息,请参见物化视图管理

STATEMENT级别的刷新

STATEMENT(语句)级别的一致性表示当基表的某一条语句执行成功时,实时物化视图中的数据将会同步变更。语句级的实时物化视图可以实现当对基表的更新语句(INSERT、COPY、UPDATE、DELETE)返回成功时,对应的物化视图的数据已经完成变化。更新逻辑如下:

  • 在数据库内核中,会先对基表执行更新,然后再执行对物化视图的更新。当基表更新失败时,物化视图中的数据不会发生变化。
  • 如果对物化视图更新失败,则基表的更新也将失败,基表将不会有任何变化,同时对基表执行的语句将返回失败。

如果使用显式事务(例如BEGIN+COMMIT),当基表的更新语句成功更新后,物化视图中的数据变更也同样在这个事务中:

  • 如果AnalyticDB PostgreSQL版为READ COMMITTED隔离级别(默认),当事务未提交时,物化视图中的更新对其他事务也不可见。
  • 如果事务回滚,基表和物化视图都会进行相应的回滚。

使用限制

AnalyticDB PostgreSQL版对实时物化视图的查询语句有所限制,您只能创建如下类型查询语句的实时物化视图:

  • 如果查询语句包含JOIN,支持使用INNER JOIN语句和OUTER JOIN语句。
  • 查询语句可以包含大部分的过滤和投影操作。
  • 如果查询语句包含OUTER JOIN,JOIN条件仅支持AND连接,不支持OR或NOT等,不支持非等值条件,不支持等值条件的左右列来自同一张表。当带有OUTER JOIN的查询语句不包含聚合操作时,JOIN列需要在投影列中。
  • 当查询语句包含聚合操作时,只支持COUNT、SUM、AVG、MAX、MIN,不支持HAVING子句。
  • 仅支持简单查询、FROM子查询及UNION ALL查询语句,不支持CTE和其它类型子查询等复杂查询语句。

当您在基表上创建了实时物化视图,对基表执行的DDL将受到限制,限制如下:

  • 对基表执行TRUNCATE命令时,实时物化视图不会同步变化,需要手动刷新物化视图或重建物化视图。
  • 只有指定了CASCADE选项,才能成功对基表执行DROP TABLE命令。
  • 基表上执行ALTER TABLE命令无法删除或修改物化视图引用的字段。

目前实时物化视图还存在部分限制,限制如下:

  • 暂时仅支持基于HEAP普通表和HEAP分区表创建实时物化视图,不支持基于AO表创建实时物化视图。
  • 暂时仅支持基于HEAP表实时物化视图创建实时物化视图,不支持基于AO表的实时物化视图或非实时物化视图创建实时物化视图。

使用场景

建议您在具有如下特征的场景使用实时物化视图:

  • 查询结果相对于对基表仅包含少量的行或列。例如具有很高过滤性的过滤条件,或者高度集中的聚合函数等场景。
  • 获取查询结果需要经过大量的计算处理,包括:
    • 半结构化数据分析。
    • 需要很长时间才能计算完成的聚合操作。
  • 在上游原始基表上创建实时物化视图,然后基于实时物化视图再创建下游实时物化视图,形成实时ETL处理链。
  • 视图的基表不会经常更改。

实时物化视图适用于所有适合使用物化视图的场景。与普通物化视图相比,实时物化视图具有高度的一致性,当基表发生改变时,实时物化视图将以较低的性能消耗同步发生改变,而普通物化视图如果每次基表发生改变,都执行刷新操作,大部分时候将消耗较大。所以当基表具有一定程度的更改,甚至需要流式导入更新时,实时物化视图相比于普通物化视图将具有很大优势。

实时物化视图代价

实时物化视图类似实时维护的索引,在对查询性能进行大幅度优化的同时,对写入性能有一定影响。

当您创建了一个只包含单表的实时物化视图时,由于需要同步更新物化视图中的数据,将会使数据库的写入性能有所下降,写入的延迟会比直接写基表的延迟多1~3倍左右,建议您在同一张基表上不要创建超过5个以上的实时物化视图。

批量写入数据有利于降低实时物化视图带来的维护开销,在使用COPY或INSERT时,适当增加在单条语句内BATCH的数据行数,可以有效降低实时物化视图的开销维护。

当创建实时物化视图的查询语句包含两表联结(JOIN)时,实时物化视图的写入性能需要进行特别调优,如果您没有相关的经验,或者测试过程中发现性能较差,建议只使用包含单表的实时物化视图。对于两表JOIN场景有如下使用建议:

  • 两张基表的JOIN KEY作为各自的分布键。
  • 两张基表的JOIN KEY必须都创建索引。

创建或删除实时物化视图

  • 使用CREATE INCREMENTAL MATERIALIZED VIEW命令创建一个名为mv实时物化视图,示例如下:
    CREATE INCREMENTAL MATERIALIZED VIEW mv AS SELECT * FROM base WHERE id > 40;
  • 使用DROP MATERIALIZED VIEW命令删除物化视图mv,示例如下:
    DROP MATERIALIZED VIEW mv;

使用示例

  1. 创建基表。示例如下:
    CREATE TABLE test (a int, b int) DISTRIBUTED BY (a);
  2. 创建实时物化视图。示例如下:
    CREATE INCREMENTAL MATERIALIZED VIEW mv AS SELECT * FROM TEST WHERE b > 40 DISTRIBUTED BY (a);
  3. 向基表插入数据。示例如下:
    INSERT INTO test VALUES (1, 30), (2, 40), (3, 50), (4, 60);
  4. 查看基表,示例如下:
    SELECT * FROM test;

    查询结果如下:

     a | b
    ---+----
     1 | 30
     2 | 40
     3 | 50
     4 | 60
    (4 rows)
  5. 查看物化视图,示例如下:
    SELECT * FROM mv;

    物化视图已经修改成功,查询结果如下:

     a | b
    ---+----
     3 | 50
     4 | 60
    (2 rows)