---
title: "刷新物化视图 - OceanBase 数据库 V4.3.2 | OceanBase 文档中心"
description: 刷新物化视图 更新基表的数据可能会导致物化视图的数据与基表的数据不一致，为了维护物化视图的数据，OceanBase 数据库会通过刷新物化视图来实现。刷新物化视图也会自动更新其所有索引。 物化视图的刷新是串行执行的，通过加对象锁来实现。在物化视图刷新时，并不会对基表加锁，以提高并发性能。 刷新模式（刷新时机） 可以使用…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.3.2

# 刷新物化视图

更新时间：2025-10-13 15:33:12

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.3.2/zh-CN/700.reference/300.database-object-management/100.manage-object-of-mysql-mode/600.manage-views-of-mysql-mode/200.manage-materialized-views-of-mysql-mode/100.materialized-views-of-mysql-mode/500.refresh-materialized-views-of-mysql-mode.md)  

更新基表的数据可能会导致物化视图的数据与基表的数据不一致，为了维护物化视图的数据，OceanBase 数据库会通过刷新物化视图来实现。刷新物化视图也会自动更新其所有索引。

物化视图的刷新是串行执行的，通过加对象锁来实现。在物化视图刷新时，并不会对基表加锁，以提高并发性能。

## 刷新模式（刷新时机）

可以使用 `ON DEMAND` 子句指定物化视图在用户需要时进行刷新。

您可以通过使用 `DBMS_MVIEW` 包手动执行刷新操作，也可以在创建物化视图时设置 `START WITH ... NEXT ...` 来指定物化视图自动定时刷新。

更多有关 `DBMS_MVIEW` 的详细信息，参见 [DBMS_MVIEW 概述](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001053769)。

## 刷新方法

### 全量刷新

#### 刷新条件

当前基表的列与物化视图对应的列类型匹配，就符合全量刷新的条件。如果不匹配，将无法进行全量刷新。

#### 刷新方式

OceanBase 数据库使用异地刷新的方式进行全量刷新，即创建一个隐藏表，在隐藏表上执行刷新语句，然后切换原表和隐藏表。因此，全量刷新操作需要额外的空间，并且会全量重建索引（如果有的话）。

#### 说明

全量刷新可能是一个非常耗时的过程，尤其是在需要读取和处理大量数据的情况下。因此，在执行全量刷新之前，您应该始终考虑处理全量刷新所需的时间。

### 增量刷新

#### 注意

- 由于 `REFRESH FAST` 方法利用物化视图日志中的记录信息来确定需要增量刷新的内容，因此在使用增量刷新刷新物化视图时，需要在创建物化视图之前就创建基表的物化视图日志（mlog）。
 - 增量刷新物化视图中使用的列都必须在 mlog 里。

有关创建物化视图日志的信息，请参见 [创建物化视图日志](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001053749)。

#### 单表增量刷新基本要求

- 不支持使用聚合函数 `MAX` 和 `MIN` 进行增量更新。
 - 不支持内联视图、`UNION` 和子查询等复杂场景的增量更新。
 - 不支持包含不稳定输出值的表达式，如 `ROWNUM` 和 `RAND` 等。
 - 不支持 `ROLLUP` 和 `HAVING`。
 - 不支持 `ORDER BY`。
 - 不支持窗口函数。
 - 如果查询中包含 `DISTINCT`，那么可增量更新的物化视图中的输出列应该是唯一的，因此在这种情况下，可以直接禁止使用 `DISTINCT`，或者将其移除。
 - 不带 `GROUP BY` 的语句必须是标量聚合（Scalar Aggregate）。
 - 对于 `GROUP BY` 场景的物化视图，仅支持 `SUM` 和 `COUNT` 等聚合函数，且聚合函数中只能使用简单的列。`GROUP BY` 的要求如下：

     1. `GROUP BY` 子句必须是标准的 `GROUP BY` 语法，不支持 `ROLLUP` 和 `HAVING`。
     2. `SELECT` 子句中必须包含所有的 `GROUP BY` 列。
     3. 聚合函数不包含 `DISTINCT` 关键字。
     4. `SELECT` 子句中必须包含 `COUNT(*)`，其它支持聚合函数及其它要求如下，目前暂不支持 `MIN` 和 `MAX` 函数。

  | **聚合函数** | **SELECT 子句中必须包含依赖列** |
  | --- | --- |
  | COUNT( expr ) | N/A |
  | SUM ( expr ) | COUNT( expr ) 或 expr 非 null |
  | AVG ( expr ) | SUM ( expr ),COUNT( expr ) |
  | STDDEV ( expr ) | SUM ( expr ),COUNT( expr ),SUM ( expr * expr ) |
  | VARIANCE ( expr ) | SUM ( expr ),COUNT( expr ),SUM ( expr * expr ) |
  | 其它可拆分为 SUM 及 COUNT 的聚合函数... (计算方式变化，可能引起精度变化) | SUM (col1),COUNT(col1) |

#### 多表简单连接增量刷新基本要求

1. `FROM` 表必须为基表，不能为内联视图、视图和物化视图等。
 2. `FROM` 表至少包含两张表，各表间仅存在内连接。
 3. `FROM` 表均存在主键，且主键在 `SELECT` 中输出。
 4. `FROM` 表均创建 mlog，且使视图中使用列均在 mlog 中存在。
 5. 视图定义中不存在子查询。
 6. 视图定义中不存在 `GROUP BY`、`ROLLUP`、`HAVING`、`WINDOW FUNCTION`、`DISTINCT`、`ORDER BY`、`LIMIT` 和 `FETCH` 等子句，为 SPJ 查询。
 7. 视图定义中不能使用 `ROWNUM`、`RAND` 和 `SYSDATE` 等不稳定输出值的表达式。

#### 增量刷新示例

1. 创建表 `test_tbl1`。

   ```sql
   CREATE TABLE test_tbl1 (col1 INT PRIMARY KEY, col2 INT, col3 INT, col4 INT);

   ```
 2. 在 `test_tbl1` 表上创建物化视图日志。

   ```sql
   CREATE MATERIALIZED VIEW LOG ON test_tbl1
     WITH SEQUENCE (col2, col3) INCLUDING NEW VALUES;

   ```
 3. 创建刷新方法是增量刷新的物化视图。

      - 创建名为 `mv1_test_tbl1` 的物化视图。指定物化视图的刷新方法为增量刷新，并且可以根据需要手动触发刷新操作；物化视图的查询部分是从表 `test_tbl1` 中选择 `col2` 列，并计算 `count(*)`、`count(col3)` 和 `sum(col3)` 的聚合结果，分组依据是 `col2` 列的值。

       ```sql
       CREATE MATERIALIZED VIEW mv1_test_tbl1
         REFRESH FAST ON DEMAND
         AS SELECT col2, count(*) cnt, count(col3) cnt_col3, sum(col3) sum_col3
            FROM test_tbl1
            GROUP BY col2;

       ```
      - 创建名为 `mv2_test_tbl1` 的物化视图。指定物化视图的刷新方法为增量刷新，并且可以根据需要手动触发刷新操作；物化视图的查询部分是从表 `test_tbl1` 中计算 `count(*)`、`count(col3)` 和 `sum(col3)` 的聚合结果。

       ```sql
       CREATE MATERIALIZED VIEW mv2_test_tbl1
         REFRESH FAST ON DEMAND
         AS SELECT count(*) cnt, count(col3) cnt_col3, sum(col3) sum_col3
            FROM test_tbl1;

       ```
      - 创建名为 `mv3_test_tbl1` 的物化视图。指定物化视图的刷新方法为增量刷新，并且可以根据需要手动触发刷新操作；物化视图的查询部分是从表 `test_tbl1` 中计算 `count(col3)` 和 `sum(col3)` 的结果。

       ```sql
       CREATE MATERIALIZED VIEW mv3_test_tbl1
         REFRESH FAST ON DEMAND
         AS SELECT count(col3) cnt_col3, sum(col3) sum_col3
            FROM test_tbl1;

       ```
      - 创建名为 `mv4_test_tbl1` 的物化视图。指定物化视图的刷新方法为增量刷新，并且可以根据需要手动触发刷新操作；物化视图的查询部分是从表 `test_tbl1` 中选择 `col2` 和 `col3` 列，并计算 `count(*)`、`count(col3)` 和 `sum(col3)` 的聚合结果，以 `col2` 和 `col3` 作为分组依据。

       ```sql
       CREATE MATERIALIZED VIEW mv4_test_tbl1
         REFRESH FAST ON DEMAND
         AS SELECT col2, col3, count(*) cnt, count(col3) cnt_col3, sum(col3) sum_col3
            FROM test_tbl1
            GROUP BY col2, col3;

       ```
      - 创建名为 `mv5_test_tbl1` 的物化视图。指定物化视图的刷新方法为增量刷新，并且可以根据需要手动触发刷新操作；物化视图的查询部分是从表 `test_tbl1` 中选择 `col2` 列，并计算 `count(*)`、`count(col3)`、`sum(col3)`、`avg(col3)` 等聚合结果，同时还计算了一些自定义的列 `calcol1` 和 `calcol2`，分组依据是 `col2` 列的值。

       ```sql
       CREATE MATERIALIZED VIEW mv5_test_tbl1
         REFRESH FAST ON DEMAND
         AS SELECT col2, count(*) cnt, count(col3) cnt_col3, sum(col3) sum_col3, avg(col3) avg_col3, avg(col3) * sum(col3)/col2 calcol1, col2+sum(col3) calcol2
            FROM test_tbl1
            GROUP BY col2;

       ```
      - 创建名为 `mv6_test_tbl1` 的物化视图。指定物化视图的刷新方法为增量刷新，并且可以根据需要手动触发刷新操作；物化视图的查询部分是从表 `test_tbl1` 中选择 `col2` 列，并计算 `count(*)`、`count(col3)`、`sum(col3)`、`count(col3*col3)`、`sum(col3*col3)` 和 `STDDEV(col3)` 的聚合结果，分组依据是 `col2` 列的值。

       ```sql
       CREATE MATERIALIZED VIEW mv6_test_tbl1
         REFRESH FAST ON DEMAND
         AS SELECT col2, count(*) cnt, count(col3) cnt_col3, sum(col3) sum_col3, count(col3*col3) cnt_col3_2, sum(col3*col3) sum_col3_2, STDDEV(col3) stddev_col3
            FROM test_tbl1
            GROUP BY col2;

       ```

#### 多表增量刷新示例

1. 创建基表 `t1` 和 `t2`。

   ```sql
   CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT, c3 INT);

   ```

   ```sql
   CREATE TABLE t2(c1 INT PRIMARY KEY, c4 INT, c5 INT);

   ```
 2. 在表 `t1` 和表 `t2` 上创建物化视图日志。

   ```sql
   CREATE MATERIALIZED VIEW LOG ON t1 WITH PRIMARY KEY, ROWID, SEQUENCE (c2) INCLUDING NEW VALUES;

   ```

   ```sql
   CREATE MATERIALIZED VIEW LOG ON t2 WITH PRIMARY KEY, ROWID, SEQUENCE (c4) INCLUDING NEW VALUES;

   ```
 3. 创建表 `t1` 和表 `t2` 连接的增量刷新的物化视图 `mv1_t1_t2`。

   ```sql
   CREATE MATERIALIZED VIEW mv1_t1_t2
     REFRESH FAST
     AS SELECT t1.c1 t1c1, t1.c2, t2.c1 t2c1, t2.c4
       FROM t1 JOIN t2 ON t1.c1=t2.c1;

   ```

#### 说明

- 为了使简单连接物化视图在增量刷新和实时物化视图中获得较好的性能，推荐按照以下方式为物化视图及其依赖基表创建索引：
     1. 为每张表的连接键创建索引，用于提升增量更新和实时物化视图中表的连接性能。
     2. 为物化视图中各基表主键列创建索引。
 - 随着物化视图中 `JOIN` 表数量的增加，物化视图的增量刷新性能和实时物化视图查询性能通常会有所下降。

**为物化视图及其依赖基表创建索引示例如下：**

1. （可选）使用以下语句删除相关测试数据。

   如果没有以下数据库对象可以跳过此步骤。

   ```sql
   DROP MATERIALIZED VIEW LOG ON t1;
   DROP TABLE IF EXISTS t1;
   DROP MATERIALIZED VIEW LOG ON t2;
   DROP TABLE IF EXISTS t2;
   DROP MATERIALIZED VIEW rt_mv1;

   ```
 2. 使用以下语句创建表 `t1` 和索引 `idx_t1_c2`。

   ```sql
   CREATE TABLE t1(c1 INT PRIMARY KEY AUTO_INCREMENT, c2 INT, c3 INT, c4 INT, c5 INT);
   CREATE INDEX idx_t1_c2 ON t1(c2);

   ```
 3. 使用以下语句创建表 `t2` 和索引 `idx_t2_c3`。

   ```sql
   CREATE TABLE t2(c1 INT PRIMARY KEY AUTO_INCREMENT, c2 INT, c3 INT, c4 INT, c5 INT);
   CREATE INDEX idx_t2_c3 ON t2(c3);

   ```
 4. 使用以下语句在 `t1` 和 `t2` 表上分别创建物化视图日志。

   ```sql
   CREATE MATERIALIZED VIEW LOG ON t1 WITH PRIMARY KEY, ROWID, SEQUENCE (c2, c3, c4) INCLUDING NEW VALUES;
   CREATE MATERIALIZED VIEW LOG ON t2 WITH PRIMARY KEY, ROWID, SEQUENCE (c2, c3, c4) INCLUDING NEW VALUES;

   ```
 5. 使用以下语句创建实时物化视图 `rt_mv1`。

   ```sql
   CREATE MATERIALIZED VIEW rt_mv1
     NEVER REFRESH
     ENABLE ON QUERY COMPUTATION
     DISABLE QUERY REWRITE
     AS SELECT t1.c1 AS t1_c1, t2.c1 AS t2_c1, t1.c2 AS t1_c2, t2.c2 AS t2_c2, t1.c3 AS t1_c3, t2.c3 AS t2_c3
         FROM t1, t2
         WHERE t1.c2 = t2.c3;

   ```
 6. 使用以下语句为物化视图中各基表主键列创建索引。

   ```sql
   CREATE INDEX idx_mv_t1_c1 ON rt_mv1(t1_c1);
   CREATE INDEX idx_mv_t2_c1 ON rt_mv1(t2_c1);

   ```

## 手动刷新物化视图

当物化视图的刷新模式是 `ON DEMAND`，可以使用 `DBMS_MVIEW` 包进行手动刷新。

#### 说明

物化视图的所有者和租户管理员用户才可以执行刷新操作。

### 使用 REFRESH 刷新物化视图

```sql
DBMS_MVIEW.REFRESH (
    IN mv_name          VARCHAR(65535),              -- 物化视图名称
    IN method           VARCHAR(65535) DEFAULT NULL, -- 刷新选项
                                                     --   f 快速刷新
                                                     --   ? 强制刷新
                                                     --   C|c 完全刷新
                                                     --   A|a 始终刷新，等价于C
    IN refresh_parallel INT DEFAULT 1);              -- 刷新并行度

```

**示例如下：**

1. 向表 `test_tbl1` 中插入 `3` 条数据。

   ```sql
   INSERT INTO test_tbl1 VALUES (1, 1, 1, 1),(2, 2, 2, 2),(3, 3, 3, 3);

   ```
 2. 查看物化视图 `mv1_test_tbl1` 信息。

   ```sql
   SELECT * FROM mv1_test_tbl1;

   ```

   返回结果如下：

   ```shell
   Empty set

   ```
 3. 使用 `DBMS_MVIEW.REFRESH` 手动刷新物化视图 `mv1_test_tbl1`。

   ```sql
   CALL DBMS_MVIEW.REFRESH('mv1_test_tbl1');

   ```
 4. 再次查看物化视图 `mv1_test_tbl1` 信息。

   ```

   返回结果如下：

   ```shell
   +------+------+----------+----------+
   | col2 | cnt  | cnt_col3 | sum_col3 |
   +------+------+----------+----------+
   |    1 |    1 |        1 |        1 |
   |    2 |    1 |        1 |        2 |
   |    3 |    1 |        1 |        3 |
   +------+------+----------+----------+
   3 rows in set

   ```

### 刷新并行度

可以通过指定 `refresh_parallel` 设置本次刷新的并行度，目前只影响全量刷新，增量刷新不受此参数影响。

**示例如下：**

指定并行度刷新物化视图。

```sql
CALL DBMS_MVIEW.REFRESH('mv1_test_tbl1', refresh_parallel => 8);

```

## 自动刷新物化视图

创建物化视图的时候，如果指定了`START WITH datetime_expr` 和 `NEXT datetime_expr` 子句，会为物化视图创建一个后台自动刷新任务。

### 刷新并行度

在后台自动刷新物化视图时，可以通过以下三种方式来指定并行度：

#### 说明

- 下述并行度优先级依次降低。
 - 刷新并行度目前只对全量刷新有影响，增量刷新不受影响。
 - 下述示例 SQL 仅作为演示并行度使用方法的参考，并不能执行。

1. 在 Hint 中指定并行度。

   **示例如下：**

   ```sql
   CREATE /*+ parallel(8) */ MATERIALIZED VIEW ...

   ```
 2. 在 DDL 的 Session 变量中指定并行度。

   **示例如下：**

      1. 启用 DDL 并行度。

        系统级别：

        ```sql
        SET _ENABLE_PARALLEL_DDL = 1;

        ```

        Session 级别：

        ```sql
        SET SESSION _ENABLE_PARALLEL_DDL = 1;

        ```
      2. 设置 DDL 并行度值

        系统级别：

        ```sql
        SET _FORCE_PARALLEL_DDL_DOP = 8;

        ```

        ```sql
        SET SESSION _FORCE_PARALLEL_DDL_DOP = 8;

        ```
 3. 创建物化视图时指定并行度（Table DOP）。

   **示例如下：**

   ```sql
   CREATE MATERIALIZED VIEW xxx PARALLEL 8 ...

   ```

## 物化视图刷新统计信息

OceanBase 系统能够收集并保存物化视图刷新操作的相关统计信息，这些信息可通过特定的视图进行查询。当前和历史物化视图刷新操作的统计信息存储在数据库中。通过历史物化视图刷新统计信息，您可以了解和分析数据库中物化视图刷新性能。

物化视图刷新的统计信息作用如下：

- 报告功能：提供物化视图刷新操作的当前及历史统计概览，包括刷新执行所需的实际时间，以便跟踪和监控刷新性能。
 - 诊断功能：通过详尽的当前和历史统计数据，能够有效地分析物化视图刷新的性能。例如，若物化视图的刷新耗时较长，统计数据可以帮助识别是系统负载增加还是因数据变更量增大导致的性能下降。

### 物化视图收集统计信息

物化视图收集统计信息。可以通过 `analyze table` 或者 `call dbms_stats.gather_table_stats('database_name', 'table_name')` 来收集统计信息。

- 更多有关收集表和列的统计信息的信息，请参见 [GATHER_TABLE_STATS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001053826)。
 - 更多有关管理物化视图刷新操作的统计信息的收集和保留的信息，请参见 [DBMS_MVIEW_STATS 概述](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001053829)。

### 展示物化视图刷新信息

| **视图名** | **功能描述** |
| --- | --- |
| [DBA_MVIEWS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001052066) | 展示物化视图信息。 |
| [DBA_MVREF_STATS_SYS_DEFAULTS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001052008) | 物化视图刷新历史统计属性的系统范围默认值。 |
| [DBA_MVREF_STATS_PARAMS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001052001) | 展示与每个物化视图关联的刷新统计信息属性。 |
| [DBA_MVREF_RUN_STATS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001051974) | 展示物化视图的每次刷新运行的信息，每次运行均由 REFRESH_ID 标识。 |
| [DBA_MVREF_STATS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001052036) | 展示物化视图刷新的基本计时统计信息。 |
| [DBA_MVREF_CHANGE_STATS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001052065) | 展示物化视图刷新相关的统计信息。 |
| [DBA_MVREF_STMT_STATS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001052056) | 展示刷新语句关联的信息。 |

## 相关文档

- [物化视图概述](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001053755)
 - [创建物化视图](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001053752)
 - [查询物化视图](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001053757)
 - [删除物化视图](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001053754)

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
