物化视图(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 等多维分析场景提供高效支持。
应用场景
物化视图通过预计算并存储查询结果来优化查询性能,特别适用于处理大规模数据和复杂查询的场景。它能够减少实时计算的开销,同时简化复杂的查询逻辑,广泛应用于快速生成报表和数据分析等领域。
-
避免重复计算 :适合存储需要频繁查询的复杂计算结果,这些查询通常资源消耗较大,使用物化视图可以避免反复计算相同的数据,从而大幅提高查询效率。
-
数据预聚合 :在报表生成和数据分析等场景中,物化视图能够提前汇总日、周或月的销售数据、用户行为数据等,预先存储计算结果,减少实时计算所需的时间和资源。
-
优化大数据查询 :当业务场景涉及大数据量的分析时,直接查询原始数据可能因频繁的大量扫描而耗时,而通过物化视图可以减少直接访问原始数据的需求,从而加速查询和分析。
-
支持多维分析 :物化视图能够预先计算不同维度组合的聚合数据,为场景化的多维数据分析提供高效且快速的查询响应能力。
参数说明
PolarDB 集群参数在控制台与会话中修改方式存在差异,详细区别如下:
-
在 PolarDB 控制台 上修改 :
-
兼容性说明 :部分集群参数在 PolarDB 控制台上均已添加 MySQL 配置文件的兼容性前缀 loose_ 。
-
操作方法 :找到并修改这些带
loose_前缀的参数。
-
-
在数据库会话中修改(使用命令行或客户端):
-
操作方法 :当您连接到数据库,使用
SET命令修改参数时,请去掉loose_前缀,直接使用参数的原始名称进行修改。
-
|
参数 |
说明 |
|
loose_materialized_view_enabled |
物化视图开关。取值范围如下:
|
|
loose_enable_materialized_view_parallel |
是否开启物化视图的并行查询功能。取值范围如下:
|
创建物化视图
语法说明
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]
[MATERIALIZED OPTIONS = 'json_options']
AS select_statement
权限要求
-
具有物化视图所在数据库的
CREATE权限。 -
具有物化视图所有基表的相关列(或整个表)的
SELECT权限。
参数说明
|
参数名 |
必填 |
说明 |
|
view_name |
是 |
物化视图的名称。 |
|
column_list |
否 |
物化视图指定列。若您希望为视图中的列指定明确的名称,可以在
|
|
REFRESH |
否 |
指定物化视图的刷新策略。
说明
本文档介绍全量刷新策略。如需使用增量刷新策略,请参见 增量刷新物化视图 。 |
|
ON |
否 |
指定物化视图的物化类型。
说明
当前仅支持异步物化视图类型。 |
|
START WITH |
否 |
异步物化视图的自动刷新起始时间。 |
|
NEXT |
否 |
异步物化视图的定时刷新时间间隔。
说明
未定义 NEXT 时,只能手动刷新。 |
|
QUERY REWRITE |
否 |
物化视图是否支持查询改写。
说明
当前不支持查询改写。 |
|
MATERIALIZED OPTIONS |
否 |
指定物化视图的扩展参数。参数值为字符串,通常使用 JSON 对象格式。详细使用方式请参见 mv_options 用法 。 |
|
select_statement |
是 |
用于定义物化视图数据的查询语句。该语句用于从基表中检索数据,并将结果存储到物化视图中。 |
mv_options 用法
mv_options
通过
MATERIALIZED OPTIONS = 'json_options'
子句指定,必须写在
AS select_statement
之前,
json_options
建议使用合法的
JSON
对象。
-
支持版本 :
-
MySQL 8.0.1 ,且内核小版本需为 8.0.1.1.55 及以上。
-
MySQL 8.0.2 ,且内核小版本需为 8.0.2.2.35 及以上。
-
-
mv_options支持以下字段 :字段
类型
取值
说明
order_keySTRING
列名或表达式文本。
设置物化视图容器表的
order_key信息。engineSTRING
-
InnoDB -
XEngine
指定物化视图容器表使用的存储引擎,大小写不敏感。
table_formatSTRING
-
row -
column
指定容器表的行存或列存格式,大小写不敏感。
-
InnoDB引擎仅支持row -
XEngine引擎支持row与column,通常和engine: "xengine"配合使用。
refresh_policySTRING
-
MASTER -
PREFER_TPRO -
PREFER_IMCI -
FORCE_TPRO -
FORCE_IMCI -
COST
指定全量刷新任务的下推策略,大小写不敏感。空串或未知值会按系统变量默认策略处理。
-
MASTER:在主节点刷新。 -
PREFER_TPRO:优先在行存只读(RO)节点刷新,若行存只读(RO)节点不存在,则在主节点刷新。 -
PREFER_IMCI:优先在列存索引只读节点刷新,若列存索引只读节点不存在,则在主节点刷新。 -
FORCE_TPRO:强制在行存只读(RO)节点刷新,若行存只读(RO)节点不存在,则报错。 -
FORCE_IMCI:强制在列存索引只读节点刷新,若列存索引只读节点不存在,则报错。 -
COST:基于查询代价,在行存只读(RO)节点或列存索引只读节点中选择其一执行刷新。
unique_checkINT
-
1 -
0
用于 XEngine 列存容器表。
-
0表示刷新期间放宽唯一性检查。 -
1或省略表示保持默认检查。
说明engine、table_format、refresh_policy、unique_check暂只支持 MySQL 8.0.2 版本。 -
-
注意事项 :
-
MATERIALIZED OPTIONS = ''会被视为未设置扩展参数。 -
SHOW CREATE TABLE输出物化视图定义时,会带出已设置的MATERIALIZED OPTIONS子句。 -
语法层只接收字符串,后续解析失败时会记录
WARNING,并按未解析到对应参数的默认行为继续处理。
-
-
示例 :
CREATE MATERIALIZED VIEW mv1 REFRESH COMPLETE ON DEMAND START WITH now() NEXT now() + INTERVAL 1 hour MATERIALIZED OPTIONS = '{"engine":"xengine","table_format":"column","order_key":"col1"}' AS SELECT col1, col2 FROM tbl1;
示例
-
创建表
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 SELECT SUM(t1.col3) AS sum_value, AVG(t1.col3) AS avg_value FROM table1 t1 JOIN table2 t2 ON t1.col1 = t2.col1; -
创建带
mv_options的物化视图。CREATE MATERIALIZED VIEW mv2 REFRESH COMPLETE ON DEMAND START WITH now() NEXT now() + INTERVAL 1 hour MATERIALIZED OPTIONS = '{"engine":"xengine","table_format":"column","refresh_policy":"FORCE_IMCI"}' SELECT t1.col1, t1.col2, t1.col3 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
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;
验证暂停/重启状态
执行
STOP
或
RESTART
命令后,可通过查询
mysql.view_materialized_info
表的
IS_STOPPED
列来确认操作是否生效。
SELECT TABLE_SCHEMA, TABLE_NAME, IS_STOPPED FROM mysql.view_materialized_info;
-
IS_STOPPED=1表示已暂停定时刷新。 -
IS_STOPPED=0表示正在运行。
IS_STOPPED
列位于
mysql.view_materialized_info
表中,而非
information_schema.materialized_view_refresh_queue
视图。该视图用于查询刷新任务队列信息,不包含
IS_STOPPED
列。