物化视图(Materialized View)是一种通过预计算和持久化存储查询结果来优化复杂查询性能的数据库对象。通过保存某些耗时操作的结果,方便在查询时直接查询已经预计算好的数据,避免重复执行这些耗时耗资源的操作,通过空间换时间来加速查询。
PolarDB MySQL版集群的物化视图现已支持全量刷新,并提供定时刷新与手动刷新两种方式。物化视图采用系统后台刷新任务机制,可结合列存索引(IMCI)加速查询,有效提升任务刷新效率,并减轻只读节点的压力。基于PolarDB的HTAP一体架构,进一步增强了AP(分析)能力。
物化视图与普通视图的主要区别在于,物化视图包含了数据的物理副本,可以直接从物化视图中查询数据。从原理上讲,物化视图是由视图及其背后的物理基表所构成。
创建物化视图:建表与物化操作被拆分为两个步骤。物化过程为异步操作,推送至后台任务,以实现物理基表的物化。物理基表的表名与视图相关联,物化刷新任务包含查询和插入两个部分,其中查询部分可以转移至列存索引只读节点,以加速查询并减轻任务对主节点的影响。
查询物化视图:通过结合视图与物理基表的方式,完成对实际物理基表的查询。
刷新物化视图:全量刷新过程需要创建一个新的隐藏物理基表。在隐藏基表上执行刷新语句后,切换原物理基表与隐藏基表,从而将最新物理基表信息更新到元数据表,并同步至内存结构中以供查询使用。
任务监控与管理:支持查询后台刷新任务队列信息,并允许对任务进行监控与管理,即在表、库或全局维度上暂停或重新启动物化视图的定时刷新任务。
适用范围
PolarDB MySQL版集群需满足以下条件之一:
MySQL 8.0.1,且内核小版本需为8.0.1.1.51及以上。
MySQL 8.0.2,且内核小版本需为8.0.2.2.31及以上。
优势
避免重复计算:对于资源消耗大的复杂查询,一次计算,多次复用,大幅提高查询效率。
数据预聚合:可预先完成对日、周、月报等数据的汇总,加速报表生成和数据分析。
优化大数据查询:减少对海量原始数据的直接扫描,加快分析查询的响应速度。
支持多维分析:能够预先计算不同维度组合的聚合数据,为OLAP等多维分析场景提供高效支持。
应用场景
物化视图通过预计算并存储查询结果来优化查询性能,特别适用于处理大规模数据和复杂查询的场景。它能够减少实时计算的开销,同时简化复杂的查询逻辑,广泛应用于快速生成报表和数据分析等领域。
避免重复计算:适合存储需要频繁查询的复杂计算结果,这些查询通常资源消耗较大,使用物化视图可以避免反复计算相同的数据,从而大幅提高查询效率。
数据预聚合:在报表生成和数据分析等场景中,物化视图能够提前汇总日、周或月的销售数据、用户行为数据等,预先存储计算结果,减少实时计算所需的时间和资源。
优化大数据查询:当业务场景涉及大数据量的分析时,直接查询原始数据可能因频繁的大量扫描而耗时,而通过物化视图可以减少直接访问原始数据的需求,从而加速查询和分析。
支持多维分析:物化视图能够预先计算不同维度组合的聚合数据,为场景化的多维数据分析提供高效且快速的查询响应能力。
创建物化视图
语法说明
CREATE
MATERIALIZED VIEW view_name [(column_list)]
[REFRESH [COMPLETE|FAST]]
[ON [COMMIT|DEMAND]]
[START WITH now()] [NEXT now() + interval 1 hour]
[[DISABLE|ENABLE] QUERY REWRITE]
AS select_statement权限要求
具有物化视图所在数据库的
CREATE权限。具有物化视图所有基表的相关列(或整个表)的
SELECT权限。
参数说明
参数名 | 必填 | 说明 |
view_name | 是 | 物化视图的名称。 |
column_list | 否 | 物化视图指定列。若您希望为视图中的列指定明确的名称,可以在 |
REFRESH | 否 | 指定物化视图的刷新策略。
说明 当前仅支持全量刷新策略。 |
ON | 否 | 指定物化视图的物化类型。
说明 当前仅支持异步物化视图类型。 |
START WITH | 否 | 异步物化视图的自动刷新起始时间。 |
NEXT | 否 | 异步物化视图的定时刷新时间间隔。 说明 未定义NEXT时,只能手动刷新。 |
QUERY REWRITE | 否 | 物化视图是否支持查询改写。
说明 当前不支持查询改写。 |
select_statement | 是 | 用于定义物化视图数据的查询语句。该语句用于从基表中检索数据,并将结果存储到物化视图中。 |
示例
创建表
table1和table2作为物化视图的基表。-- 创建基表 CREATE TABLE table1 (col1 INT PRIMARY KEY, col2 VARCHAR(20), col3 INT); CREATE TABLE table2 (col1 INT PRIMARY KEY, col2 VARCHAR(20), col3 INT); -- 向基表中插入数据 INSERT INTO table1 VALUES (1, 'A', 100), (2, 'B', 200), (3, 'C', 300), (4, 'D', 400); INSERT INTO table2 VALUES (1, 'X', 10), (2, 'Y', 20), (3, 'Z', 30), (5, 'W', 50);创建物化视图。
CREATE MATERIALIZED VIEW mv1 REFRESH COMPLETE ON DEMAND START WITH now() NEXT now() + INTERVAL 1 hour AS SELECT SUM(t1.col3) AS sum_value, AVG(t1.col3) AS avg_value FROM table1 t1 JOIN table2 t2 ON t1.col1 = t2.col1;
查询物化视图
查询物化视图需具备物化视图的SELECT权限,无需具备物化视图所引用基表的SELECT权限。
查询物化视图
SELECT * FROM mv1;预期返回结果:
+-----------+-----------+
| sum_value | avg_value |
+-----------+-----------+
| 600 | 200.0000 |
+-----------+-----------+查询物化视图定义
SHOW CREATE VIEW mv1;预期返回结果:
+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View | Create View | character_set_client | collation_connection |
+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| mv1 | CREATE MATERIALIZED VIEW `mv1` REFRESH COMPLETE ON DEMAND START WITH ('2025-10-15 11:20:15') NEXT (now() + interval 1 hour) AS select sum(`t1`.`col3`) AS `sum_value`,avg(`t1`.`col3`) AS `avg_value` from (`table1` `t1` join `table2` `t2` on((`t1`.`col1` = `t2`.`col1`))) | utf8mb4 | utf8mb4_0900_ai_ci |
+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+使用系统表查询物化视图信息
SELECT * FROM mysql.view_materialized_info;表字段说明
字段 | 说明 |
TABLE_SCHEMA | 物化视图所在的数据库名。 |
TABLE_NAME | 物化视图的名称。 |
IS_DROPPED | 是否已删除。
|
FIRST_REFRESH_TIME | 如果已配置自动刷新,则表示首次刷新的时间。 |
TIME_ZONE | 时区设置。 |
REFRESH_CONDITION | 刷新的触发机制。
|
REFRESH_STRATEGY | 物化视图的刷新策略。
|
REFRESH_START_TIME | 启动刷新的时间。 |
NEXT_TIME_EXPRESSION | 异步物化视图的下次刷新时间定义。 |
LAST_START_TIME | 上次实际启动刷新的时间。 |
LAST_END_TIME | 上次实际刷新结束的时间。 |
CONTAINER_TABLE_POSTFIX | 数据存储物理表的后缀。 |
EXPIRED_TABLE_POSTFIX | 下一个过期数据存储物理表的后缀。 |
IS_STOPPED | 是否已停止定时刷新。
|
CREATE_TIME | 物化视图元信息的创建时间。 |
UPDATE_TIME | 物化视图元信息的更新时间。 |
预期返回结果:
+-----+--------------+------------+------------+---------------------+-----------+-------------------+------------------+---------------------+---------------------------+---------------------+---------------------+-------------------------+-----------------------+------------+---------------------+---------------------+
| id | table_schema | table_name | is_dropped | first_refresh_time | time_zone | refresh_condition | refresh_strategy | refresh_start_time | next_time_expression | last_start_time | last_end_time | container_table_postfix | expired_table_postfix | is_stopped | create_time | update_time |
+-----+--------------+------------+------------+---------------------+-----------+-------------------+------------------+---------------------+---------------------------+---------------------+---------------------+-------------------------+-----------------------+------------+---------------------+---------------------+
| 471 | testmv | mv1 | 0 | 2025-10-15 11:20:16 | +08:00 | DEMAND | COMPLETE | 2025-10-15 11:20:15 | (now() + interval 1 hour) | 2025-10-15 11:20:15 | 2025-10-15 11:20:16 | 2022929596417 | 2022929596417 | 0 | 2025-10-15 11:20:16 | 2025-10-15 11:20:16 |
+-----+--------------+------------+------------+---------------------+-----------+-------------------+------------------+---------------------+---------------------------+---------------------+---------------------+-------------------------+-----------------------+------------+---------------------+---------------------+刷新物化视图
目前,物化视图仅支持全量刷新。这一过程采用异地刷新的方式进行全量刷新,即创建一个隐藏的物理基表,在该隐藏基表上执行刷新语句,随后切换原物理基表与隐藏基表。因此,全量刷新的操作需要额外的存储空间。其主要优势在于能够支持任意SQL查询。
物化视图支持两种刷新方式,即手动刷新和定时刷新。
手动刷新
如果物化视图未配置定时刷新,或者定时刷新间隔较大时,可通过手动刷新命令REFRESH MATERIALIZED VIEW来实现数据刷新。
REFRESH MATERIALIZED VIEW <view_name>;示例
插入新测试数据。
INSERT INTO table1 VALUES (5, 'E', 500), (6, 'F', 600); INSERT INTO table2 VALUES (7, 'U', 60), (8, 'V', 70);手动刷新物化视图。
REFRESH MATERIALIZED VIEW mv1;查询物化视图。
SELECT * FROM mv1;预期返回结果:
+-----------+-----------+ | sum_value | avg_value | +-----------+-----------+ | 1100 | 275.0000 | +-----------+-----------+
定时刷新
在创建物化视图时,支持设置定时刷新起始时间START WITH以及配置自动刷新的时间间隔NEXT。系统将根据设置的刷新时间配置,自动调度刷新机制。
CREATE MATERIALIZED VIEW mv1
REFRESH COMPLETE
ON DEMAND
START WITH now() NEXT now() + INTERVAL 1 hour
AS
SELECT
SUM(t1.col3) AS sum_value,
AVG(t1.col3) AS avg_value
FROM table1 t1
JOIN table2 t2 ON t1.col1 = t2.col1;删除物化视图
删除物化视图需具有物化视图所在数据库的DROP权限。
语法说明
DROP MATERIALIZED VIEW <view_name>;示例
DROP MATERIALIZED VIEW mv1;定时刷新任务监控与管理
物化视图的定时刷新依赖于系统的自动调度刷新机制。当调度任务数量过多时,您可以对任务进行监控与管理,即在表、库或全局维度上暂停或重新启动物化视图的定时刷新任务。
查看任务队列
通过系统视图information_schema.materialized_view_refresh_queue,可以查询刷新队列信息。
SELECT * FROM information_schema.materialized_view_refresh_queue;暂停任务队列
以表维度
STOP MATERIALIZED VIEW task FOR TABLE mv1;以库维度
STOP MATERIALIZED VIEW task FOR DATABASE mv1;以全局维度
STOP MATERIALIZED VIEW task FOR ALL;重启任务队列
以表维度
RESTART MATERIALIZED VIEW task FOR TABLE mv1;以库维度
RESTART MATERIALIZED VIEW task FOR DATABASE mv1;以全局维度
RESTART MATERIALIZED VIEW task FOR ALL;