Updating data in base tables may result in inconsistency between the data of the materialized view and the data of the base tables. To maintain the consistency of the data of the materialized view, OceanBase Database automatically refreshes the materialized view. Refreshing a materialized view also updates all its indexes automatically.
Refresh mode (specifies when to refresh)
You can use the ON DEMAND clause to specify that a materialized view be refreshed when data is requested.
You can manually refresh a materialized view by using the DBMS_MVIEW package, or you can specify the START WITH ... NEXT ... clause when you create a materialized view to have it automatically refreshed on a scheduled basis.
For more information about the DBMS_MVIEW package, see Overview of DBMS_MVIEW.
Refresh methods
Complete refreshes
Prerequisites
A complete refresh is possible if the data types of all columns in the source table are compatible with those in the materialized view. Otherwise, the complete refresh cannot be performed.
Refresh approach
OceanBase Database performs complete refreshes by remote refresh. Specifically, it creates a hidden table, executes the refresh statement on the hidden table, and then switches the source table and the hidden table. Therefore, additional space and time are required for a complete refresh, and the indexes (if any) are fully rebuilt.
Note
Incremental refreshes
Notice
- The
REFRESH FASTmethod uses records in mlogs to determine the data that needs to be incrementally refreshed. Therefore, to incrementally refresh a materialized view, you must create mlogs for the base table before you create the materialized view. - Columns used for incremental refreshing of materialized views must exist in mlogs.
Basic requirements for incremental refreshes of single tables
The
MAXandMINaggregate functions are not supported.Complex scenarios such as inline views,
UNION, and subqueries are not supported.Expressions that generate unstable output values, such as
ROWNUMandRAND, are not supported.The
ROLLUPandHAVINGclauses are not supported.The
ORDER BYclause is not supported.Window functions are not supported.
If the query contains the
DISTINCTkeyword, the output column of the materialized view that supports incremental refreshes must be unique. In this case, you can either disable theDISTINCTkeyword or remove it.A statement without the
GROUP BYclause must be a scalar aggregate (Scalar Aggregate) statement.For materialized views in the
GROUP BYscenario, only aggregate functions such asSUMandCOUNTare supported, and only simple columns can be used in the aggregate functions. TheGROUP BYclause must meet the following requirements:- The
GROUP BYclause must be in the standardGROUP BYsyntax and cannot includeROLLUPorHAVING. - The
SELECTclause must contain all theGROUP BYcolumns. - The aggregate functions cannot include the
DISTINCTkeyword, and the parameters of the aggregate functions must be basic columns. - The
SELECTclause must containCOUNT(*). Other aggregate functions are supported, and the following aggregate functions are currently not supported:MINandMAX.
Aggregate function SELECT clause must contain a dependency column COUNT( expr ) N/A SUM ( expr ) COUNT( expr ) or expr is not 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 ) Other aggregate functions that can be decomposed into SUM and COUNT... (The calculation method may vary, which may result in precision loss.) SUM (col1),COUNT(col1) - The
Basic requirements for incremental refreshes of simple join queries across multiple tables
- The
FROMtable must be a base table and cannot be an inline view, view, or materialized view. - The
FROMtable must contain at least two tables connected by inner joins. The number of joined tables must be less than or equal to 5. - The
FROMtable must have a primary key, and the primary key must be output in theSELECTclause. - Mlogs must be created for the
FROMtable, and the columns used in the view must be included in the mlogs. - The view definition must not contain subqueries.
- The view definition must not contain the
GROUP BY,ROLLUP,HAVING,WINDOW FUNCTION,DISTINCT,ORDER BY,LIMIT, orFETCHclause. It must be a standard SQL query. - The view definition must not contain expressions that generate unstable output values, such as
ROWNUM,RAND, andSYSDATE.
Incremental refresh example
Create a table named
test_tbl1.CREATE TABLE test_tbl1 (col1 INT PRIMARY KEY, col2 INT, col3 INT, col4 INT);Create an mlog on the
test_tbl1table.CREATE MATERIALIZED VIEW LOG ON test_tbl1 WITH SEQUENCE (col2, col3) INCLUDING NEW VALUES;Create materialized views with the incremental refresh method.
Create a materialized view named
mv1_test_tbl1. Set the refresh method of the materialized view to incremental and specify that the refresh can be manually triggered as needed; the query part of the materialized view returns thecol2column from thetest_tbl1table and calculates the aggregate results ofcount(*),count(col3), andsum(col3)based on the values of thecol2column.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;Create a materialized view named
mv2_test_tbl1. Set the refresh method of the materialized view to incremental and specify that the refresh can be manually triggered as needed; the query part of the materialized view calculates the aggregate results ofcount(*),count(col3), andsum(col3)based on all rows in thetest_tbl1table.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;Create a materialized view named
mv3_test_tbl1. Set the refresh method of the materialized view to incremental and specify that the refresh can be manually triggered as needed; the query part of the materialized view calculates the results ofcount(col3)andsum(col3)based on all rows in thetest_tbl1table.CREATE MATERIALIZED VIEW mv3_test_tbl1 REFRESH FAST ON DEMAND AS SELECT count(col3) cnt_col3, sum(col3) sum_col3 FROM test_tbl1;Create a materialized view named
mv4_test_tbl1. Set the refresh method of the materialized view to incremental and specify that the refresh can be manually triggered as needed; the query part of the materialized view returns thecol2andcol3columns from thetest_tbl1table, and calculates the aggregate results ofcount(*),count(col3), andsum(col3)based on the values of thecol2andcol3columns as grouping keys.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;Create a materialized view named
mv5_test_tbl1. Set the refresh method of the materialized view to incremental and specify that the refresh can be manually triggered as needed; the query part of the materialized view returns thecol2column from thetest_tbl1table, and calculates the aggregate results ofcount(*),count(col3),sum(col3), andavg(col3), and some custom columnscalcol1andcalcol2, based on the values of thecol2column as grouping keys.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;Create a materialized view named
mv6_test_tbl1. Set the refresh method of the materialized view to incremental and specify that the refresh can be manually triggered as needed; the query part of the materialized view returns thecol2column from thetest_tbl1table, and calculates the aggregate results ofcount(*),count(col3),sum(col3),count(col3*col3),sum(col3*col3), andSTDDEV(col3)based on the values of thecol2column as grouping keys.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;
Example of incremental refreshes across multiple tables
Create base tables
t1andt2.CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT, c3 INT);CREATE TABLE t2(c1 INT PRIMARY KEY, c4 INT, c5 INT);Create mlogs for tables
t1andt2.CREATE MATERIALIZED VIEW LOG ON t1 WITH PRIMARY KEY, ROWID, SEQUENCE (c2) INCLUDING NEW VALUES;CREATE MATERIALIZED VIEW LOG ON t2 WITH PRIMARY KEY, ROWID, SEQUENCE (c4) INCLUDING NEW VALUES;Create the
mv1_t1_t2materialized view that incrementally refreshes the join result of tablest1andt2.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;
Manually refresh a materialized view
If the refresh mode of a materialized view is ON DEMAND, you can manually refresh the materialized view by using the DBMS_MVIEW package.
Note
Only the owner of the materialized view and the tenant administrator have the privilege to perform refresh operations.
Refresh a materialized view by using the REFRESH procedure
DBMS_MVIEW.REFRESH (
IN mv_name VARCHAR(65535), -- The name of the materialized view.
IN method VARCHAR(65535) DEFAULT NULL, -- The refresh options.
-- f specifies to perform fast refreshes.
-- ? specifies to perform forcible refreshes.
-- C|c specifies to perform complete refreshes.
-- A|a specifies to always perform refreshes, which is equivalent to C.
IN refresh_parallel INT DEFAULT 1); -- The degree of parallelism of the refresh.
Here is an example:
Insert three records into the
test_tbl1table.INSERT INTO test_tbl1 VALUES (1, 1, 1, 1),(2, 2, 2, 2),(3, 3, 3, 3);Query the
mv1_test_tbl1materialized view.SELECT * FROM mv1_test_tbl1;The return result is as follows:
Empty setManually refresh the
mv1_test_tbl1materialized view by using theDBMS_MVIEW.REFRESHprocedure.CALL DBMS_MVIEW.REFRESH('mv1_test_tbl1');Query the
mv1_test_tbl1materialized view again.SELECT * FROM mv1_test_tbl1;The return result is as follows:
+------+------+----------+----------+ | col2 | cnt | cnt_col3 | sum_col3 | +------+------+----------+----------+ | 1 | 1 | 1 | 1 | | 2 | 1 | 1 | 2 | | 3 | 1 | 1 | 3 | +------+------+----------+----------+ 3 rows in set
Degree of parallelism
You can set the refresh_parallel parameter to specify the degree of parallelism of the refresh. Currently, this parameter applies only to complete refreshes and has no effect on incremental refreshes.
Here is an example:
Refresh a materialized view in parallel.
CALL DBMS_MVIEW.REFRESH('mv1_test_tbl1', refresh_parallel => 8);
## Automatic refresh of materialized views
If you specify the `START WITH datetime_expr` and `NEXT datetime_expr` clauses when you create a materialized view, an automatic refresh task is created for the materialized view in the background.
### Degree of parallelism
When the system automatically refreshes a materialized view in the background, you can specify the degree of parallelism in the following three ways:
<main id="notice" type='explain'>
<h4>Note</h4>
<p><ul><li>The specified degree of parallelism takes effect for full refreshes only. It does not apply to incremental refreshes.</li><li>The following examples of SQL statements are for demonstration purposes only. They show how to specify the degree of parallelism and cannot be executed. </li></ul></p>
</main>
1. Specify the degree of parallelism in the hint.
**Here is an example:**
```sql
CREATE /*+ parallel(8) */ MATERIALIZED VIEW ...
```
2. Specify the degree of parallelism in the session variables of the DDL statement.
**Here is an example:**
1. Enable parallel DDL.
At the system level:
```sql
SET _ENABLE_PARALLEL_DDL = 1;
```
At the session level:
```sql
SET SESSION _ENABLE_PARALLEL_DDL = 1;
```
2. Set the value of the degree of parallelism.
At the system level:
```sql
SET _FORCE_PARALLEL_DDL_DOP = 8;
```
At the session level:
```sql
SET SESSION _FORCE_PARALLEL_DDL_DOP = 8;
```
3. Specify the degree of parallelism when you create a materialized view (table DOP).
**Here is an example:**
```sql
CREATE MATERIALIZED VIEW xxx PARALLEL 8 ...
```
## Statistics on materialized view refreshes
OceanBase Database can collect and store statistics on materialized view refreshes. These statistics can be queried from specific views. Current and historical statistics on materialized view refreshes are stored in the database. You can analyze the historical statistics on materialized view refreshes to understand the refresh performance in the database.
The statistics on materialized view refreshes serve the following purposes:
* Reporting: provides a summary of the actual execution time of refreshes, both current and historical, to help you track and monitor refresh performance.
* Diagnostics: detailed statistics can help you analyze the performance of refreshes. For example, if a refresh takes a long time, statistics can help you determine whether the performance degradation is caused by increased system load or data change volume.
### Statistics collection for materialized views
Statistics are collected for materialized views. You can use the `analyze table` statement or the `call dbms_stats.gather_table_stats('database_name', 'table_name')` procedure to collect statistics.
* For more information about how to collect statistics on tables and columns, see [GATHER_TABLE_STATS](../../../../../500.sql-reference/300.pl-reference/200.pl-mysql/1000.pl-system-package-mysql/15900.dbms-stats-mysql/1700.gather-table-stats-mysql.md).
* For more information about how to collect statistics on materialized view refreshes, see [DBMS_MVIEW_STATS overview](../../../../../500.sql-reference/300.pl-reference/200.pl-mysql/1000.pl-system-package-mysql/10050.dbms-mview-stat-mysql/100.dbms-mview-stat-overview-mysql.md).
### Views displaying materialized view refresh information
| **View name** | **Description** |
|------------|--------------|
| [DBA_MVIEWS](../../../../../700.system-views/400.system-view-of-mysql-mode/200.dictionary-view-of-mysql-mode/5000.o-dba_mviews-of-mysql-mode.md) | Displays information about materialized views. |
| [DBA_MVREF_STATS_SYS_DEFAULTS](../../../../../700.system-views/400.system-view-of-mysql-mode/200.dictionary-view-of-mysql-mode/5500.o-dba_mvref_stats_sys_defaults-of-mysql-mode.md) | System-level default values of statistics attributes for materialized view refreshes. |
| [DBA_MVREF_STATS_PARAMS](../../../../../700.system-views/400.system-view-of-mysql-mode/200.dictionary-view-of-mysql-mode/5400.o-dba_mvref_stats_params-of-mysql-mode.md) | Displays the refresh statistics attributes associated with each materialized view. |
| [DBA_MVREF_RUN_STATS](../../../../../700.system-views/400.system-view-of-mysql-mode/200.dictionary-view-of-mysql-mode/5200.o-dba_mvref_run_stats-of-mysql-mode.md) | Displays information about each refresh of materialized views. Each refresh is identified by the REFRESH_ID attribute. |
| [DBA_MVREF_STATS](../../../../../700.system-views/400.system-view-of-mysql-mode/200.dictionary-view-of-mysql-mode/5300.o-dba_mvref_stats-of-mysql-mode.md) | Displays basic timing statistics about materialized view refreshes. |
| [DBA_MVREF_CHANGE_STATS](../../../../../700.system-views/400.system-view-of-mysql-mode/200.dictionary-view-of-mysql-mode/5100.o-dba_mvref_change_stats-of-mysql-mode.md) | Displays statistics about materialized view refreshes. |
| [DBA_MVREF_STMT_STATS](../../../../../700.system-views/400.system-view-of-mysql-mode/200.dictionary-view-of-mysql-mode/5600.o-dba_mvref_stmt_stats-of-mysql-mode.md) | Displays information about refresh statements. |
## References
* [Overview of materialized views](100.materialized-views-overview-of-mysql-mode.md)
* [Create materialized views](200.create-materialized-views-of-mysql-mode.md)
* [Query materialized views](300.view-materialized-views-of-mysql-mode.md)
* [Drop materialized views](400.delete-materialized-views-of-mysql-mode.md)