CREATE MATERIALIZED VIEW
功能
创建物化视图。关于物化视图适用的场景请参考同步物化视图和异步物化视图。
创建物化视图是一个异步的操作。该命令执行成功即代表创建物化视图的任务提交成功。您可以通过 SHOW ALTER MATERIALIZED VIEW 命令查看当前数据库中同步物化视图的构建状态,或通过查询 Information Schema 中的 tasks 和 task_runs 来查看异步物化视图的构建状态。
- 只有拥有基表所在数据库的 CREATE MATERIALIZED VIEW 权限的用户才可以创建物化视图。
- 自 v3.4.0 起,StarRocks 存算分离集群支持同步物化视图。
StarRocks 自 v2.4 起支持异步物化视图。异步物化视图与先前版本中的同步物化视图区别主要体现在以下方面:
| 单表聚合 | 多表关联 | 查询改写 | 刷新策略 | 基表 | |
|---|---|---|---|---|---|
| 异步物化视图 | 是 | 是 | 是 |
| 支持多表构建。基表可以来自:
|
| 同步物化视图(Rollup) | 仅部分聚合函数 | 否 | 是 | 导入同步刷新 | 仅支持基于 Default Catalog 的单表构建 |
同步物化视图
语法
CREATE MATERIALIZED VIEW [IF NOT EXISTS] [database.]<mv_name>
[COMMENT ""]
[PROPERTIES ("key"="value", ...)]
AS
<query_statement>
参数
mv_name(必填)
物化视图的名称。命名要求如下:
- 必须由字母(a-z 或 A-Z)、数字(0-9)或下划线(_)组成,且只能以字母开头。
- 总长度不能超过 64 个字符。
- 视图名大小写敏感。
COMMENT(选填)
物化视图的注释。注意建立物化视图时 COMMENT 必须在 mv_name 之后,否则创建失败。
query_statement(必填)
创建物化视图的查询语句,其结果即为物化视图中的数据。语法如下:
SELECT select_expr[, select_expr ...]
[WHERE where_expr]
[GROUP BY column_name[, column_name ...]]
[ORDER BY column_name[, column_name ...]]
-
select_expr(必填)
构建同步物化视图的查询语句。
- 单列或聚合列:形如
SELECT a, b, c FROM table_a,其中a、b和c为基表的列名。如果您没有为物化视图指定列名,那么 StarRocks 自动为这些列命名。 - 表达式:形如
SELECT a+1 AS x, b+2 AS y, c*c AS z FROM table_a,其中a+1、b+2和c*c为包含基表列名的表达式,x、y和z为物化视图的列名。
说明
- 该参数至少需包含一个单列。
- 使用聚合函数创建同步物化视图时,必须指定 GROUP BY 子句,并在
select_expr中指定至少一个 GROUP BY 列。 - 同步物化视图不支持 JOIN、以及 GROUP BY 的 HAVING 子句。
- 从 v3.1 开始,每个同步物化视图支持为基表的每一列使用多个聚合函数,支持形如
select b, sum(a), min(a) from table group by b形式的查询语句。 - 从 v3.1 开始,同步物化视图支持 SELECT 和聚合函数的复杂表达式,即形如
select b, sum(a + 1) as sum_a1, min(cast (a as bigint)) as min_a from table group by b或select abs(b) as col1, a + 1 as col2, cast(a as bigint) as col3 from table的查询语句。同步物化视图的复杂表达式有以下限制:- 每个复杂表达式必须有一个列名,并且基表所有同步物化视图中的不同复杂表达式的别名必须不同。例如,查询语句
select b, sum(a + 1) as sum_a from table group by b和select b, sum(a) as sum_a from table group by b不能同时用于为相同的基表创建同步物化视图,你可以为同一复杂表达式设置多个不同别名。 - 您可以通过执行
EXPLAIN <sql_statement>来查看您的查询是否被使用复杂表达式创建的同步物化视图改写。更多信息请参见查询分析。
- 每个复杂表达式必须有一个列名,并且基表所有同步物化视图中的不同复杂表达式的别名必须不同。例如,查询语句
- 单列或聚合列:形如
-
WHERE (选填)
自 v3.1.8 起,同步物化视图支持通过 WHERE 子句筛选数据。
-
GROUP BY(选填)
构建物化视图查询语句的分组列。如不指定该参数,则默认不对数据进行分组。
-
ORDER BY(选填)
构建物化视图查询语句的排序列。
-
排序列的声明顺序必须和
select_expr中列声明顺序一致。 -
如果查询语句中包含 分组列,则排序列必须和分组列一致。
-
如果不指定排序列,则系统根据以下规则自动补充排序列:
- 如果物化视图是聚合类型,则所有的分组列自动补充为排序列。
- 如果物化视图是非聚合类型,则系统根据前缀列自动选择排序列。
-
查询同步物化视图
因为同步物化视图本质上是基表的索引而不是物理表,所以您只能使用 Hint [_SYNC_MV_] 查询同步物化视图:
-- 请勿省略 Hint 中的括号[]。
SELECT * FROM <mv_name> [_SYNC_MV_];
目前,StarRocks 会自动为同步物化视图中的列生成名称。您为同步物化视图中的列指定的 Alias 将无法生效。
同步物化视图查询自动改写
使用同步物化视图查询时,原始查询语句将会被自动改写并用于查询物化视图中保存的中间结果。
下表展示了原始查询聚合函数和构建同步物化视图用到的聚合函数的匹配关系。您可以根据业务场景选择对应的聚合函数构建同步物化视图。
| 原始查询聚合函数 | 物化视图构建聚合函数 |
|---|---|
| sum | sum |
| min | min |
| max | max |
| count | count |
| bitmap_union, bitmap_union_count, count(distinct) | bitmap_union |
| hll_raw_agg, hll_union_agg, ndv, approx_count_distinct | hll_union |
除了上述函数外,从 StarRocks v3.4.0 开始,同步物化视图还支持通用聚合函数。有关通用聚合函数的更多信息,请参见通用聚合函数状态。
-- Create a synchronous materialized view test_mv1 to store aggregate states.
CREATE MATERIALIZED VIEW test_mv1
AS
SELECT
dt,
-- Original aggregate functions.
min(id) AS min_id,
max(id) AS max_id,
sum(id) AS sum_id,
bitmap_union(to_bitmap(id)) AS bitmap_union_id,
hll_union(hll_hash(id)) AS hll_union_id,
percentile_union(percentile_hash(id)) AS percentile_union_id,
-- Generic aggregate state functions.
ds_hll_count_distinct_union(ds_hll_count_distinct_state(id)) AS hll_id,
avg_union(avg_state(id)) AS avg_id,
array_agg_union(array_agg_state(id)) AS array_agg_id,
min_by_union(min_by_state(province, id)) AS min_by_province_id
FROM t1
GROUP BY dt;
异步物化视图
语法
CREATE MATERIALIZED VIEW [IF NOT EXISTS] [database.]<mv_name>
[COMMENT ""]
-- 必须至少指定 `distribution_desc` 和 `refresh_scheme` 其中之一。
-- distribution_desc
[DISTRIBUTED BY HASH(<bucket_key>[,<bucket_key2> ...]) [BUCKETS <bucket_number>]]
-- refresh_desc
[REFRESH
-- refresh_moment
[IMMEDIATE | DEFERRED]
-- refresh_scheme
[ASYNC | ASYNC [START (<start_time>)] EVERY (INTERVAL <refresh_interval>) | MANUAL]
]
-- partition_expression
[PARTITION BY
[ <partition_column> [,...] ] | [ <date_function_expr> ]
]
-- order_by_expression
[ORDER BY (<sort_key>)]
[PROPERTIES ("key"="value", ...)]
AS
<query_statement>
参数
mv_name(必填)
物化视图的名称。命名要求如下:
- 必须由字母(a-z 或 A-Z)、数字(0-9)或下划线(_)组成,且只能以字母开头。
- 总长度不能超过 64 个字符。
- 视图名大小写敏感。
同一张基表可以创建多个异步物化视图,但同一数据库内的异步物化视图名称不可重复。
COMMENT(选填)
物化视图的注释。注意建立物化视图时 COMMENT 必须在 mv_name 之后,否则创建失败。
distribution_desc(选填)
异步物化视图的分桶方式,包括哈希分桶和随机分桶(自 3.1 版本起)。如不指定该参数,StarRocks 使用随机分桶方式,并自动设置分桶数量。
创建异步物化视图时必须至少指定 distribution_desc 和 refresh_scheme 其中之一。
-
哈希分桶:
语法
DISTRIBUTED BY HASH (<bucket_key1>[,<bucket_key2> ...]) [BUCKETS <bucket_number>]更多信息,请参见 分桶。
说明
自 2.5.7 版本起,StarRocks 支持在建表和新增分区时自动设置分桶数量 (BUCKETS),您无需手动设置分桶数量。更多信息,请参见 设置分桶数量。
-
随机分桶:
如果您选择随机分桶方式,并且自动设置分桶数量,则无需指定
distribution_desc。如果您需要手动设置分桶数,请使用以下语法:DISTRIBUTED BY RANDOM BUCKETS <bucket_number>注意
采用随机分桶方式的异步物化视图不支持设置 Colocation Group。
更多信息,请参见 随机分桶。
refresh_moment(选填)
物化视图的刷新时刻。默认值:IMMEDIATE。有效值:
IMMEDIATE:异步物化视图创建成功后立即刷新。DEFERRED:异步物化视图创建成功后不进行刷新。您可以通过手动调用或创建定时任务触发刷新。
refresh_scheme(选填)
创建异步物化视图时必须至少指定 distribution_desc 和 refresh_scheme 其中之一。
物化视图的刷新方式。该参数支持如下值:
ASYNC: 自动刷新模式。每当基表数据发生变化时,物化视图会自动刷新。ASYNC [START (<start_time>)] EVERY(INTERVAL <interval>): 定时刷新模式。物化视图将按照定义的间隔定时刷新。您可以使用DAY(天)、HOUR(小时)、MINUTE(分钟)和SECOND(秒)作为单位指定间隔,格式为EVERY (interval n day/hour/minute/second)。默认值为10 MINUTE(10 分钟)。您还可以进一步指定刷新起始时间,格式为START('yyyy-MM-dd hh:mm:ss')。如未指定起始时间,默认使用当前时间。示例:ASYNC START ('2023-09-12 16:30:25') EVERY (INTERVAL 5 MINUTE)。MANUAL: 手动刷新模式。除非手动触发刷新任务,否则物化视图不会刷新。
如果不指定该参数,则默认使用 MANUAL 方式。
partition_expression(选填)
异步物化视图的分区表达式。如不指定该参数,则默认物化视图为无分区。
该参数支持如下值:
partition_column:用于分区的列。形如PARTITION BY dt,表示按照dt列进行分区。date_function_expr:用于分区的日期函数复杂表达式。date_trunc函数:形如PARTITION BY date_trunc("MONTH", dt),表示将dt列截断至以月为单位进行分区。date_trunc 函数支持截断的单位包括YEAR、MONTH、DAY、HOUR以及MINUTE。str2date函数:用于将基表的字符串类型分区键转化为物化视图的分区键所需的日期类型。PARTITION BY str2date(dt, "%Y%m%d")表示dt列是一个 STRING 类型日期,其日期格式为"%Y%m%d"。str2date函数支持多种日期格式。更多信息,参考str2date。自 v3.1.4 起支持。time_slice函数:从 v3.1 开始,您可以进一步使用 time_slice 函数根据指定的时间粒度周期,将给定的时间转化到其所在的时间粒度周期的起始或结束时刻,例如PARTITION BY date_trunc("MONTH", time_slice(dt, INTERVAL 7 DAY)),其中 time_slice 的时间粒度必须比date_trunc的时间粒度更细。你可以使用它们来指定一个比分区键更细时间粒度的 GROUP BY 列,例如,GROUP BY time_slice(dt, INTERVAL 1 MINUTE) PARTITION BY date_trunc('DAY', ts)。
自 v3.5.0 起,异步物化视图支持多列分区表达式。您可以为物化视图指定多个分区列映射基表的全部或者部分分区列。
多列分区表达式相关说明:
-
当前物化视图支持的多列分区只能与基表的分区列直接映射,不支持基表分区列+函数表达式加工后映射。
-
由于 Iceberg 分区表达式支持 Transform 功能,若 Iceberg 的分区表达式映射到 StarRocks 时,需要额外处理 分区表达式。以下为两者对应关系:
Iceberg Transform Iceberg 分区表达式 物化视图分区表达式 Identity <col><col>hour hour(<col>)date_trunc('hour', <col>)day day(<col>)date_trunc('day', <col>)month month(<col>)date_trunc('month', <col>)year year(<col>)date_trunc('year', <col>)bucket bucket(<col>, <n>)Not supported truncate truncate(<col>)Not supported -
对于非 Iceberg 类型的分区列,因不涉及分区表达式计算,创建物化视图时只需直接选择映射,不需要额外的分区表达式处理。
有关多列分区表达式的详细指导,参考 示例五。