跳到主要内容
版本: 最新版本-3.5

异步物化视图

本主题介绍如何理解、创建、使用和管理异步物化视图。StarRocks v2.4 及更高版本支持异步物化视图。

与同步物化视图相比,异步物化视图支持多表 Join 和更多聚合函数。异步物化视图的刷新可以手动触发,也可以按照预先指定的时间间隔定期触发,或者在基表数据发生更改时自动触发。您还可以刷新部分分区,而不是整个物化视图,从而大大降低刷新成本。此外,异步物化视图支持多种查询重写场景,从而实现自动、透明的查询加速。

有关同步物化视图(Rollup)的场景和用法,请参见 同步物化视图(Rollup)

概述

数据库中的应用程序通常对大型表执行复杂的查询。此类查询涉及多表 Join 和对包含数十亿行的表进行聚合。处理这些查询的成本可能很高,无论是系统资源方面还是计算结果所需的时间方面。

StarRocks 中的异步物化视图旨在解决这些问题。异步物化视图是一种特殊的物理表,其中包含来自一个或多个基表的预先计算的查询结果。当您对基表执行复杂的查询时,StarRocks 会返回来自相关物化视图的预先计算的结果来处理这些查询。这样,可以提高查询性能,因为避免了重复的复杂计算。当查询频繁运行或足够复杂时,这种性能差异可能非常显着。

此外,异步物化视图对于在数据仓库上构建数学模型特别有用。通过这样做,您可以向上层应用程序提供统一的数据规范,屏蔽底层实现,或者保护基表的原始数据安全性。

了解 StarRocks 中的物化视图

StarRocks v2.3 及更早版本提供了一种同步物化视图,该物化视图只能在单个表上构建。同步物化视图(或 Rollup)保留较高的数据新鲜度和较低的刷新成本。但是,与 v2.4 及更高版本支持的异步物化视图相比,同步物化视图有很多限制。当您要构建同步物化视图以加速或重写查询时,聚合运算符的选择有限。

下表从它们支持的功能的角度比较了 StarRocks 中的异步物化视图 (ASYNC MV) 和同步物化视图 (SYNC MV)

单表聚合多表 Join查询重写刷新策略基表
ASYNC MV
  • 异步刷新
  • 手动刷新
来自多个表
  • 默认 Catalog
  • 外部 Catalog (v2.5)
  • 现有物化视图 (v2.5)
  • 现有视图 (v3.1)
SYNC MV (Rollup)聚合函数的选择有限数据加载期间的同步刷新默认 Catalog 中的单个表

基本概念

  • 基表

    基表是物化视图的驱动表。

    对于 StarRocks 的异步物化视图,基表可以是 默认 Catalog 中的 StarRocks 原生表、外部 Catalog 中的表(v2.5 起支持),甚至是现有的异步物化视图(v2.5 起支持)和视图(v3.1 起支持)。StarRocks 支持在所有 StarRocks 表类型上创建异步物化视图。

  • 刷新

    创建异步物化视图时,其数据仅反映当时基表的状态。当基表中的数据发生更改时,您需要刷新物化视图以保持更改同步。

    目前,StarRocks 支持两种通用刷新策略

    • ASYNC:异步刷新模式。当基表中的数据发生更改时,可以自动刷新物化视图,也可以根据指定的时间间隔定期刷新。
    • MANUAL:手动刷新模式。物化视图不会自动刷新。刷新任务只能由用户手动触发。
  • 查询重写

    查询重写意味着在对构建了物化视图的基表执行查询时,系统会自动判断物化视图中的预先计算的结果是否可以重用于该查询。如果可以重用,系统将直接从相关的物化视图加载数据,以避免耗时且耗费资源的计算或 Join。

    从 v2.5 开始,StarRocks 支持基于 SPJG 类型的异步物化视图的自动、透明的查询重写。SPJG 类型物化视图是指其计划仅包括 Scan、Filter、Project 和 Aggregate 类型的运算符的物化视图。

    注意

    在 JDBC Catalog 或 Hudi Catalog 中的基表上创建的异步物化视图不支持查询重写。

决定何时创建物化视图

如果在您的数据仓库环境中存在以下需求,您可以创建异步物化视图

  • 使用重复的聚合函数加速查询

    假设您的数据仓库中的大多数查询都包含具有聚合函数的相同子查询,并且这些查询已消耗了您的大部分计算资源。基于此子查询,您可以创建一个异步物化视图,该视图将计算并存储子查询的所有结果。构建物化视图后,StarRocks 会重写所有包含子查询的查询,加载存储在物化视图中的中间结果,从而加速这些查询。

  • 多个表的定期 JOIN

    假设您需要定期 Join 数据仓库中的多个表以生成一个新的宽表。您可以为这些表构建一个异步物化视图,并设置以固定时间间隔触发刷新任务的 ASYNC 刷新策略。构建物化视图后,查询结果将直接从物化视图返回,从而避免了 JOIN 操作造成的延迟。

  • 数据仓库分层

    假设您的数据仓库包含大量原始数据,并且其中的查询需要一组复杂的 ETL 操作。您可以构建多个异步物化视图层以对数据仓库中的数据进行分层,从而将查询分解为一系列简单的子查询。它可以显着减少重复计算,更重要的是,可以帮助您的 DBA 轻松高效地识别问题。除此之外,数据仓库分层有助于分离原始数据和统计数据,从而保护敏感原始数据的安全性。

  • 加速数据湖中的查询

    由于网络延迟和对象存储吞吐量,查询数据湖可能很慢。您可以通过在数据湖之上构建异步物化视图来提高查询性能。此外,StarRocks 可以智能地重写查询以使用现有的物化视图,从而省去手动修改查询的麻烦。

有关异步物化视图的特定用例,请参阅以下内容

创建异步物化视图

可以在以下基表上创建 StarRocks 的异步物化视图

  • StarRocks 的原生表(支持所有 StarRocks 表类型)
  • 外部 Catalog 中的表
  • 现有的异步物化视图(自 v2.5 起)
  • 现有的视图(自 v3.1 起)

准备工作

以下示例涉及默认 Catalog 中的两个基表

  • goods 记录商品 ID item_id1、商品名称 item_name 和商品价格 price
  • order_list 记录订单 ID order_id、客户端 ID client_id、商品 ID item_id2 和订单日期 order_date

goods.item_id1 等效于列 order_list.item_id2

执行以下语句以创建表并将数据插入其中

CREATE TABLE goods(
item_id1 INT,
item_name STRING,
price FLOAT
) DISTRIBUTED BY HASH(item_id1);

INSERT INTO goods
VALUES
(1001,"apple",6.5),
(1002,"pear",8.0),
(1003,"potato",2.2);

CREATE TABLE order_list(
order_id INT,
client_id INT,
item_id2 INT,
order_date DATE
) DISTRIBUTED BY HASH(order_id);

INSERT INTO order_list
VALUES
(10001,101,1001,"2022-03-13"),
(10001,101,1002,"2022-03-13"),
(10002,103,1002,"2022-03-13"),
(10002,103,1003,"2022-03-14"),
(10003,102,1003,"2022-03-14"),
(10003,102,1001,"2022-03-14");

以下示例中的场景需要频繁计算每个订单的总计。它需要频繁 Join 两个基表并密集使用聚合函数 sum()。此外,业务场景要求数据以一天的时间间隔刷新。

查询语句如下

SELECT
order_id,
sum(goods.price) as total
FROM order_list INNER JOIN goods ON goods.item_id1 = order_list.item_id2
GROUP BY order_id;

创建物化视图

您可以基于特定的查询语句使用 CREATE MATERIALIZED VIEW 创建物化视图。

基于表 goodsorder_list 和上述查询语句,以下示例创建物化视图 order_mv 以分析每个订单的总计。物化视图设置为以一天的时间间隔自行刷新。

CREATE MATERIALIZED VIEW order_mv
DISTRIBUTED BY HASH(`order_id`)
REFRESH ASYNC START('2022-09-01 10:00:00') EVERY (interval 1 day)
AS SELECT
order_list.order_id,
sum(goods.price) as total
FROM order_list INNER JOIN goods ON goods.item_id1 = order_list.item_id2
GROUP BY order_id;

注意

  • 创建异步物化视图时,必须指定物化视图的数据分发策略或刷新策略,或者两者都指定。
  • 您可以为异步物化视图设置与其基表不同的分区和分桶策略,但必须在用于创建物化视图的查询语句中包含物化视图的分区键和分桶键。
  • 异步物化视图支持更长时间跨度的动态分区策略。例如,如果基表以一天的时间间隔进行分区,则可以将物化视图设置为以一个月的时间间隔进行分区。
  • 从 v3.3.3 开始,StarRocks 支持使用 List 分区策略创建异步物化视图。
    • 您可以基于使用 List 分区或表达式分区策略创建的表创建列表分区物化视图。
    • 目前,在使用 List 分区策略创建物化视图时,只能指定一个分区键。如果基表有多个分区键,则必须选择一个分区键。
    • 使用 List 分区策略的物化视图的刷新行为和查询重写逻辑与使用 Range 分区策略的物化视图一致。
  • 用于创建物化视图的查询语句不支持随机函数,包括 rand()、random()、uuid() 和 sleep()。
  • 异步物化视图支持各种数据类型。有关更多信息,请参见 CREATE MATERIALIZED VIEW - 支持的数据类型
  • 默认情况下,执行 CREATE MATERIALIZED VIEW 语句会立即触发刷新任务,这会消耗一定比例的系统资源。如果您想延迟刷新任务,可以将 REFRESH DEFERRED 参数添加到 CREATE MATERIALIZED VIEW 语句中。
  • 物化视图只能在 default_catalog 中创建。您可以创建带有 default_catalog.database.mv 的物化视图,也可以通过 set catalog <default_catalog> 语句切换到 default_catalog。
  • 关于异步物化视图的刷新机制

    目前,StarRocks 支持两种 ON DEMAND 刷新策略:MANUAL 刷新和 ASYNC 刷新。

    在 StarRocks v2.5 中,异步物化视图进一步支持多种异步刷新机制,以控制刷新成本并提高成功率

    • 如果 MV 有许多大型分区,则每次刷新都会消耗大量资源。在 v2.5 中,StarRocks 支持拆分刷新任务。您可以指定要刷新的最大分区数,StarRocks 会分批执行刷新,批处理大小小于或等于指定的最大分区数。此功能可确保稳定刷新大型异步物化视图,从而增强数据建模的稳定性和鲁棒性。
    • 您可以为异步物化视图的分区指定生存时间 (TTL),从而减少物化视图占用的存储大小。
    • 您可以指定刷新范围以仅刷新最新的几个分区,从而减少刷新开销。
    • 您可以指定数据更改不会自动触发相应物化视图刷新的基表。
    • 您可以为刷新任务分配一个资源组。

    有关更多信息,请参见 CREATE MATERIALIZED VIEW - 参数 中的 PROPERTIES 部分。您还可以使用 ALTER MATERIALIZED VIEW 修改现有异步物化视图的机制。

    注意

    为了防止完整刷新操作耗尽系统资源并导致任务失败,建议基于分区基表创建分区物化视图。这样可以确保当基表分区中发生数据更新时,仅刷新物化视图的相应分区,而不是刷新整个物化视图。有关更多信息,请参阅 使用物化视图进行数据建模 - 分区建模

  • 关于嵌套物化视图

    StarRocks v2.5 支持创建嵌套异步物化视图。您可以基于现有的异步物化视图构建异步物化视图。每个物化视图的刷新策略不会影响上层或下层的物化视图。目前,StarRocks 不限制嵌套级别的数量。在生产环境中,我们建议嵌套层数不超过 THREE。

  • 关于外部 Catalog 物化视图

    StarRocks 支持基于 Hive Catalog(自 v2.5 起)、Hudi Catalog(自 v2.5 起)、Iceberg Catalog(自 v2.5 起)和 JDBC Catalog(自 v3.0 起)构建异步物化视图。在外部 Catalog 上创建物化视图类似于在默认 Catalog 上创建异步物化视图,但有一些使用限制。有关更多信息,请参阅 使用物化视图加速数据湖查询

手动刷新异步物化视图

您可以通过 REFRESH MATERIALIZED VIEW 刷新异步物化视图,而不管其刷新策略如何。StarRocks v2.5 支持通过指定分区名称来刷新异步物化视图的特定分区。StarRocks v3.1 支持对刷新任务进行同步调用,并且仅当任务成功或失败时才返回 SQL 语句。

-- Refresh the materialized view via an asynchronous call (default).
REFRESH MATERIALIZED VIEW order_mv;
-- Refresh the materialized view via a synchronous call.
REFRESH MATERIALIZED VIEW order_mv WITH SYNC MODE;

您可以使用 CANCEL REFRESH MATERIALIZED VIEW 取消通过异步调用提交的刷新任务。

直接查询异步物化视图

您创建的异步物化视图本质上是一个物理表,其中包含根据查询语句预先计算的完整结果集。因此,您可以在首次刷新物化视图后直接查询物化视图。

MySQL > SELECT * FROM order_mv;
+----------+--------------------+
| order_id | total |
+----------+--------------------+
| 10001 | 14.5 |
| 10002 | 10.200000047683716 |
| 10003 | 8.700000047683716 |
+----------+--------------------+
3 rows in set (0.01 sec)

注意

您可以直接查询异步物化视图,但结果可能与您从查询其基表获得的结果不一致。

使用异步物化视图重写和加速查询

StarRocks v2.5 支持基于 SPJG 类型的异步物化视图的自动和透明查询重写。SPJG 类型物化视图查询重写包括单表查询重写、Join 查询重写、聚合查询重写、Union 查询重写和基于嵌套物化视图的查询重写。从 v3.3.0 开始,StarRocks 进一步支持基于文本的物化视图重写。有关更多信息,请参阅 使用物化视图进行查询重写

目前,StarRocks 支持重写在默认 Catalog 或外部 Catalog(例如 Hive Catalog、Hudi Catalog 或 Iceberg Catalog)上创建的异步物化视图的查询。在查询默认 Catalog 中的数据时,StarRocks 通过排除数据与基表不一致的物化视图来确保重写查询和原始查询之间的结果具有强一致性。当物化视图中的数据过期时,该物化视图将不会用作候选物化视图。在查询外部 Catalog 中的数据时,StarRocks 不确保结果具有强一致性,因为 StarRocks 无法感知外部 Catalog 中的数据更改。有关基于外部 Catalog 创建的异步物化视图的更多信息,请参阅 使用物化视图加速数据湖查询

注意

在 JDBC Catalog 中的基表上创建的异步物化视图不支持查询重写。

管理异步物化视图

更改异步物化视图

您可以使用 ALTER MATERIALIZED VIEW 更改异步物化视图的属性。

  • 启用非活动物化视图。

    ALTER MATERIALIZED VIEW order_mv ACTIVE;
  • 重命名异步物化视图。

    ALTER MATERIALIZED VIEW order_mv RENAME order_total;
  • 将异步物化视图的刷新间隔更改为 2 天。

    ALTER MATERIALIZED VIEW order_mv REFRESH ASYNC EVERY(INTERVAL 2 DAY);

显示异步物化视图

您可以使用 SHOW MATERIALIZED VIEWS 或查询 Information Schema 中的系统元数据视图来查看数据库中的异步物化视图。

  • 检查数据库中的所有异步物化视图。

    SHOW MATERIALIZED VIEWS;
  • 检查特定的异步物化视图。

    SHOW MATERIALIZED VIEWS WHERE NAME = "order_mv";
  • 通过匹配名称检查特定的异步物化视图。

    SHOW MATERIALIZED VIEWS WHERE NAME LIKE "order%";
  • 通过查询 Information Schema 中的元数据视图 materialized_views 来检查所有异步物化视图。有关更多信息,请参阅 information_schema.materialized_views

    SELECT * FROM information_schema.materialized_views;

检查异步物化视图的定义

您可以通过 SHOW CREATE MATERIALIZED VIEW 检查用于创建异步物化视图的查询。

SHOW CREATE MATERIALIZED VIEW order_mv;

检查异步物化视图的执行状态

您可以通过查询 Information Schema 中的 taskstask_runs 来检查异步物化视图的执行(构建或刷新)状态。

以下示例检查最近创建的物化视图的执行状态

  1. 在表 tasks 中检查最近任务的 TASK_NAME

    mysql> select * from information_schema.tasks  order by CREATE_TIME desc limit 1\G;
    *************************** 1. row ***************************
    TASK_NAME: mv-59299
    CREATE_TIME: 2022-12-12 17:33:51
    SCHEDULE: MANUAL
    DATABASE: ssb_1
    DEFINITION: insert overwrite hive_mv_lineorder_flat_1 SELECT `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_orderkey`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_linenumber`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_custkey`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_partkey`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_orderpriority`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_ordtotalprice`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_revenue`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`p_mfgr`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`s_nation`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`c_city`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`c_nation`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_orderdate`
    FROM `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`
    WHERE `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_orderdate` = '1997-01-01'
    EXPIRE_TIME: NULL
    1 row in set (0.02 sec)
  2. 使用您找到的 TASK_NAME 在表 task_runs 中检查执行状态。

    mysql> select * from information_schema.task_runs where task_name='mv-59299' order by CREATE_TIME\G
    *************************** 1. row ***************************
    QUERY_ID: d9cef11f-7a00-11ed-bd90-00163e14767f
    TASK_NAME: mv-59299
    CREATE_TIME: 2022-12-12 17:39:19
    FINISH_TIME: 2022-12-12 17:39:22
    STATE: SUCCESS
    DATABASE: ssb_1
    DEFINITION: insert overwrite hive_mv_lineorder_flat_1 SELECT `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_orderkey`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_linenumber`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_custkey`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_partkey`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_orderpriority`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_ordtotalprice`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_revenue`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`p_mfgr`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`s_nation`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`c_city`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`c_nation`, `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_orderdate`
    FROM `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`
    WHERE `hive_ci`.`dla_scan`.`lineorder_flat_1000_1000_orc`.`lo_orderdate` = '1997-01-01'
    EXPIRE_TIME: 2022-12-15 17:39:19
    ERROR_CODE: 0
    ERROR_MESSAGE: NULL
    PROGRESS: 100%
    2 rows in set (0.02 sec)

删除异步物化视图

您可以通过 DROP MATERIALIZED VIEW 删除异步物化视图。

DROP MATERIALIZED VIEW order_mv;

相关会话变量

以下变量控制异步物化视图的行为

  • analyze_mv:是否以及如何在刷新后分析物化视图。有效值为空字符串(不分析)、sample(采样统计信息收集)和 full(完整统计信息收集)。默认值为 sample
  • enable_materialized_view_rewrite:是否启用物化视图的自动重写。有效值为 true(自 v2.5 以来的默认值)和 false