物化视图类似于视图,允许用户保存经常使用的或复杂的查询。物化视图有实际的物理储存,但不支持直接写入更新数据。在查询中引用物化视图时,数据直接从物化视图返回。物化视图的数据不会自动刷新,因此可能不是最新的,但是访问物化视图中的数据要比直接或通过视图访问底层表中的数据快得多。物化视图在用户能够容忍定期更新数据的情况下拥有巨大的性能优势。
AnalyticDB PostgreSQL版Serverless版本暂不支持物化视图功能。
创建物化视图
使用命令CREATE MATERIALIZED VIEW
创建一个查询的物化视图。
CREATE MATERIALIZED VIEW my_materialized_view as
SELECT * FROM people WHERE age > 40
DISTRIBUTED BY (id);
SELECT * from my_materialized_view ORDER BY age;
返回信息如下:
id | name | city | age
------------+------------+------------+-----
004 | zhaoyi | zhenzhou | 44
005 | xuliui | jiaxing | 54
006 | maodi | shanghai | 55
(3 rows)
物化视图定义中的查询仅用于填充物化视图。物化视图定义和普通表的定义一样(除了不能指定OID)。DISTRIBUTED BY在创建时可选,若没有该语句会选择默认的第一个可分区列进行分区。
物化视图会忽略存储在物化视图中的ORDER BY以及SORT操作。
刷新或禁用物化视图
使用REFRESH MATERIALIZED VIEW
命令刷新物化视图数据。
INSERT INTO people VALUES('007','sunshen','shenzhen',60);
SELECT * from my_materialized_view ORDER BY age;
返回信息如下:
id | name | city | age
------------+------------+------------+-----
004 | zhaoyi | zhenzhou | 44
005 | xuliui | jiaxing | 54
006 | maodi | shanghai | 55
(3 rows)
REFRESH MATERIALIZED VIEW my_materialized_view;
SELECT * from my_materialized_view ORDER BY age;
返回信息如下:
id | name | city | age
------------+------------+------------+-----
004 | zhaoyi | zhenzhou | 44
005 | xuliui | jiaxing | 54
006 | maodi | shanghai | 55
007 | sunshen | shenzhen | 60
(4 rows)
使用With NO DATA
子句会删除当前数据且不生成新数据,还会使物化视图处于无法扫描状态。如果试图查询无法扫描状态的物化视图,将返回一个错误。
REFRESH MATERIALIZED VIEW my_materialized_view With NO DATA;
SELECT * from my_materialized_view ORDER BY age;
ERROR: materialized view "my_materialized_view" has not been populated
HINT: Use the REFRESH MATERIALIZED VIEW command.
REFRESH MATERIALIZED VIEW my_materialized_view;
SELECT * from my_materialized_view ORDER BY age;
返回信息如下:
id | name | city | age
------------+------------+------------+-----
004 | zhaoyi | zhenzhou | 44
005 | xuliui | jiaxing | 54
006 | maodi | shanghai | 55
007 | sunshen | shenzhen | 60
(4 rows)
删除物化视图
使用DROP MATERIALIZED VIEW
命令删除一个物化视图。
CREATE MATERIALIZED VIEW depend_materialized_view as
SELECT * FROM my_materialized_view WHERE age > 50
DISTRIBUTED BY (id);
DROP MATERIALIZED VIEW depend_materialized_view;
使用DROP MATERIALIZED VIEW ... CASCADE
命令还会删除所有依赖该物化视图的对象。例如,如果另一个物化视图依赖于即将被删除的物化视图,那么另一个物化视图也将被删除。
如果没有CASCADE选项,DROP MATERIALIZED VIEW命令就会失败。
CREATE MATERIALIZED VIEW depend_materialized_view as
SELECT * FROM my_materialized_view WHERE age > 50
DISTRIBUTED BY (id);
DROP MATERIALIZED VIEW my_materialized_view;
ERROR: cannot drop materialized view my_materialized_view because other objects depend on it
DETAIL: materialized view depend_materialized_view depends on materialized view my_materialized_view
HINT: Use DROP ... CASCADE to drop the dependent objects too.
DROP MATERIALIZED VIEW my_materialized_view CASCADE;
适用场景
可以容忍数据不是最新或者定期手动更新的场景。
经常使用的或者特别复杂的查询。
物化视图结合外部数据源(如OSS外表、MaxCompute外表)可以实现更快的查询分析。外部数据通过物化视图实现本地存储,同时也可以对物化视图创建索引。