This topic describes the CREATE MATERIALIZED VIEW statement, which you can use to create materialized views that support complete or fast refresh and configure their refresh schedule.
Syntax
CREATE [OR REPLACE] MATERIALIZED VIEW mv_name
[mv_definition]
[mv_properties]
[REFRESH {COMPLETE|FAST}]
[ON {DEMAND|OVERWRITE}]
[START WITH date] [NEXT date]
[{DISABLE|ENABLE} QUERY REWRITE]
[COMMENT 'view_comment']
AS
query_body
mv_definition:
({column_name column_type [column_attributes] [ column_constraints ] [COMMENT 'column_comment']
| table_constraints}
[, ... ])
[table_attribute]
[partition_options]
[index_all]
[storage_policy]
[block_size]
[engine]
[table_properties]Parameters
OR REPLACE | Optional | Changeable after creation: no | |
Only AnalyticDB for MySQL clusters of V3.1.4.7 or later support this parameter.
| |||
mv_definition | Optional | Changeable after creation: no | |
You can define the structure of the materialized view. You can choose whether to explicitly define the schema of a materialized view. If you do not explicitly define the schema, AnalyticDB for MySQL uses the columns from the query_body results as the materialized view columns, defines a primary key, creates indexes on all columns, configures hot data storage, and sets the engine to XUANWU. To manually define the schema—including distribution keys, partition keys, primary keys, indexes, and tiered storage policies for hot and cold data—use the same method as for the CREATE TABLE statement. For example, if you do not need to index all columns, use the INDEX keyword to specify which columns to index. To reduce storage costs, set the storage policy to mixed hot-and-cold storage or retain only the last year of data. Primary key rules
RecommendationsTo optimize query performance, define a primary key, a distribution key, and a partition key when you create a materialized view. | |||
mv_properties | Optional | Changeable after creation: yes (using the ALTER MATERIALIZED VIEW statement) | |
Only AnalyticDB for MySQL Enterprise Edition, Basic Edition, or Data Lakehouse Edition clusters of V3.1.9.3 or later support this parameter. The resource policy for the materialized view, including the resource group used (mv_resource_group) and configuration hints for refresh tasks (mv_refresh_hints). This parameter uses JSON format. Example: mv_resource_groupThe resource group used to create and refresh the materialized view. If you do not specify one, the default resource group user_default is used. You can set this to an interactive resource group or a job resource group powered by the XIHE engine. Job resource groups require seconds or minutes to provision resources. If you tolerate higher refresh latency, use a job resource group. Materialized views that use job resource groups are called elastic materialized views. To improve the refresh speed of elastic materialized views, configure elastic_job_max_acu in mv_refresh_hints to increase the maximum resource limit. See the elastic materialized view example. You can view available resource groups on the Resource Groups page in the console or call the DescribeDBResourceGroup operation. If the specified resource group does not exist, an error occurs when you create the materialized view. mv_refresh_hintsSpecifies the configuration parameters for materialized views. For a list of supported parameters and their usage, see Common Hints. | |||
REFRESH [COMPLETE | FAST] | Optional | Default value: COMPLETE | Changeable after creation: no |
The refresh policy for the materialized view. For differences between policies and applicable scenarios, see How to choose a refresh policy. COMPLETEComplete refresh runs the original query SQL each time, scans all target partitions of the base table, and overwrites old data with newly computed data. Complete refresh supports these trigger mechanisms: on-demand manual refresh, scheduled automatic refresh ( FASTOnly AnalyticDB for MySQL clusters of V3.1.9.0 or later support this parameter. V3.1.9.0 supports only single-table materialized views with fast refresh. V3.2.0.0 or later supports both single-table and multi-table materialized views with fast refresh. Fast refresh rewrites the materialized view query (query_body) to scan only changed data in the base table (INSERT, DELETE, UPDATE), process it, and write it to the materialized view. This avoids scanning all base table data and reduces per-refresh compute overhead. Before creating a materialized view with fast refresh, enable binary logging for the cluster and base tables. Otherwise, creation fails. See Enable binary logging. Materialized views with fast refresh must use scheduled automatic refresh. Define the next refresh time using Materialized views with fast refresh have specific limits. If the query_body does not support fast refresh, creation fails. | |||
ON [DEMAND | OVERWRITE] | Optional | Default value: DEMAND | Changeable after creation: no |
The refresh trigger mechanism for the materialized view. For differences between mechanisms and applicable scenarios, see How to choose a refresh trigger mechanism. DEMANDOn-demand refresh. Manually trigger a refresh or use the Materialized views with fast refresh support only OVERWRITEAutomatic refresh when the base table is overwritten by an If you set the trigger mechanism to | |||
[START WITH date] [NEXT date] | Optional | Changeable after creation: no | |
Define the refresh time only when the trigger mechanism is START WITHThe first refresh time. If omitted, the first refresh occurs at creation time. NEXTThe next refresh time.
dateTime functions are supported but must be accurate to the second. Milliseconds are truncated. | |||
[DISABLE | ENABLE] QUERY REWRITE | Optional | Default value: DISABLE | Changeable after creation: yes (using the ALTER MATERIALIZED VIEW statement) |
This parameter is supported only by versions 3.1.4 and later. Enables or disables query rewrite for the materialized view. For details, see Query rewrite for materialized views. DISABLEDisables query rewrite for the materialized view. ENABLEEnables query rewrite for the materialized view. After enabling, the optimizer rewrites full or partial queries based on SQL patterns and routes them to the materialized view. This avoids computing on base tables and improves query performance. | |||
query_body | Required | Changeable after creation: no | |
The base table query for the materialized view. For a materialized view with full refresh, the base tables can be internal tables, external tables, existing materialized views, and views in AnalyticDB for MySQL. There are no restrictions on the base table query. For more information about the query syntax, see SELECT. For a materialized view with incremental refresh, the base tables can only be internal tables in AnalyticDB for MySQL. The base table query must follow these rules: SELECT output columns
Other limits
| |||
Required permissions
To create a materialized view, the user must have all of the following permissions:
The CREATE permission on the database where the materialized view will be created.
The SELECT permission on the relevant columns or the entire base tables of the materialized view.
If you want to create an auto-refresh materialized view, you also need the following permissions:
Permission to connect to AnalyticDB for MySQL from any IP address (
'%').The INSERT permission on the view itself, or on all tables in its database, is required to refresh the data in the materialized view.
Examples
Example preparation
The materialized view examples below use the base tables defined in this section. To try the examples, first run the SQL statements here to create the base tables.
/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */ -- Specify XUANWU as the table engine.
CREATE TABLE customer (
customer_id INT PRIMARY KEY,
customer_name VARCHAR(255),
is_vip Boolean
);/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */ -- Specify XUANWU as the table engine.
CREATE TABLE sales (
sale_id INT PRIMARY KEY,
product_id INT,
customer_id INT,
price DECIMAL(10, 2),
quantity INT,
sale_date TIMESTAMP
);Full Refresh of a Materialized View
Create a materialized view named
myview1that refreshes every 5 minutes.CREATE MATERIALIZED VIEW myview1 REFRESH -- Equivalent to REFRESH COMPLETE. NEXT now() + INTERVAL 5 minute AS SELECT count(*) as cnt FROM customer;Create a materialized view named
myview2that refreshes daily at 02:00:00.CREATE MATERIALIZED VIEW myview2 REFRESH COMPLETE START WITH DATE_FORMAT(now() + INTERVAL 1 day, '%Y-%m-%d 02:00:00') NEXT DATE_FORMAT(now() + INTERVAL 1 day, '%Y-%m-%d 02:00:00') AS SELECT count(*) as cnt FROM customer;Create a materialized view named
myview3that refreshes every Monday at 02:00:00.CREATE MATERIALIZED VIEW myview3 REFRESH COMPLETE ON DEMAND START WITH DATE_FORMAT(now() + INTERVAL 7 - weekday(now()) day, '%Y-%m-%d 02:00:00') NEXT DATE_FORMAT(now() + INTERVAL 7 - weekday(now()) day, '%Y-%m-%d 02:00:00') AS SELECT count(*) as cnt FROM customer;Create a materialized view named
myview4that refreshes on the first day of each month at 02:00:00.CREATE MATERIALIZED VIEW myview4 REFRESH -- Equivalent to REFRESH COMPLETE. NEXT DATE_FORMAT(last_day(now()) + INTERVAL 1 day, '%Y-%m-%d 02:00:00') AS SELECT count(*) as cnt FROM customer;Create a materialized view named
myview5that refreshes only once.CREATE MATERIALIZED VIEW myview5 REFRESH -- Equivalent to REFRESH COMPLETE. START WITH now() + INTERVAL 1 day AS SELECT count(*) as cnt FROM customer;Create a materialized view named
myview6that does not refresh automatically. Refresh it manually.CREATE MATERIALIZED VIEW myview6 ( PRIMARY KEY (customer_id) ) DISTRIBUTED BY HASH (customer_id) AS SELECT customer_id FROM customer;Manually refresh the materialized view:
REFRESH MATERIALIZED VIEW myview6;Create a materialized view named
myview7that refreshes automatically when the base table is overwritten. No manual refresh time is needed.CREATE MATERIALIZED VIEW myview7 REFRESH COMPLETE ON OVERWRITE AS SELECT count(*) as cnt FROM customer;
Create a single-table materialized view that supports fast refresh
Before you create a materialized view that supports fast refresh, enable binary logging for the cluster and base tables.
SET ADB_CONFIG BINLOG_ENABLE=true;
ALTER TABLE customer binlog=true;
ALTER TABLE sales binlog=true;
Create a single-table materialized view named fast_mv1 that supports fast refresh at 10-second intervals. The materialized view query does not involve an aggregate function.
CREATE MATERIALIZED VIEW fast_mv1 REFRESH FAST NEXT now() + INTERVAL 10 second AS SELECT sale_id, sale_date, price FROM sales WHERE price > 10;Create a single-table materialized view named fast_mv2 that supports fast refresh at 5-second intervals. The materialized view query involves an aggregate function with GROUP BY.
CREATE MATERIALIZED VIEW fast_mv2 REFRESH FAST NEXT now() + INTERVAL 5 second AS SELECT customer_id, sale_date, -- The system uses the GROUP BY columns as the primary key of the materialized view. COUNT(sale_id) AS cnt_sale_id, -- Perform an aggregate operation on a column. SUM(price * quantity) AS total_revenue, -- Perform an aggregate operation on a column. customer_id / 100 AS new_customer_id -- You can use an expression to define columns that are not involved in aggregate operations. FROM sales WHERE ifnull(price, 1) > 0 -- You can use an expression to define WHERE conditions. GROUP BY customer_id, sale_date;Create a single-table materialized view named fast_mv3 that supports fast refresh at 1-minute intervals. The materialized view query involves an aggregate function without GROUP BY.
CREATE MATERIALIZED VIEW fast_mv3 REFRESH FAST NEXT now() + INTERVAL 1 minute AS SELECT count(*) AS cnt -- The system generates a constant as the primary key to ensure that only one record is contained in the materialized view. FROM sales;
Create a multi-table materialized view that supports fast refresh
Create a multi-table materialized view named fast_mv4 that supports fast refresh at 5-second intervals and does not use aggregation.
CREATE MATERIALIZED VIEW fast_mv4 REFRESH FAST NEXT now() + INTERVAL 5 second AS SELECT c.customer_id, c.customer_name, s.sale_id, (s.price * s.quantity) AS revenue FROM sales s JOIN customer c ON s.customer_id = c.customer_id;Create a multi-table materialized view named fast_mv5 that supports fast refresh at 10-second intervals and uses grouped aggregation.
CREATE MATERIALIZED VIEW fast_mv5 REFRESH FAST NEXT now() + INTERVAL 10 second AS SELECT s.sale_id, c.customer_name, COUNT(*) AS cnt, SUM(s.price * s.quantity) AS revenue FROM sales s JOIN (SELECT customer_id, customer_name FROM customer) c ON c.customer_id = s.customer_id GROUP BY s.sale_id, c.customer_name;
Partitioned materialized view
Create a materialized view named myview8 with a distribution key and a partition key.
CREATE MATERIALIZED VIEW myview8 (
quantity INT, -- The materialized view includes all columns from the query results even if no columns are explicitly displayed.
price DECIMAL(10, 2),
sale_date TIMESTAMP
)
DISTRIBUTED BY HASH(sale_id)
PARTITION BY VALUE(date_format(sale_date, "%Y%m%d")) LIFECYCLE 30
AS
SELECT * FROM sales;Explicitly define primary key, distribution key, indexes, etc.
Create a materialized view named
myview9that indexes only thecustomer_namecolumn.CREATE MATERIALIZED VIEW myview9 ( INDEX (sale_date), PRIMARY KEY (sale_id) ) DISTRIBUTED BY HASH (sale_id) REFRESH NEXT now() + INTERVAL 1 DAY AS SELECT * FROM sales;Create a materialized view named
myview10that defines a primary key, a distribution key, a clustered index, a column-based index, and a comment.CREATE MATERIALIZED VIEW myview10 ( quantity INT, -- The materialized view includes all columns from the query results even if no columns are explicitly displayed. price DECIMAL(10, 2), KEY INDEX_ID(customer_id) COMMENT 'customer', CLUSTERED KEY INDEX(sale_id), PRIMARY KEY(sale_id,sale_date) ) DISTRIBUTED BY HASH(sale_id) COMMENT 'MATERIALIZED VIEW c' AS SELECT * FROM sales;
Elastic Materialized View
Create an elastic materialized view named
myview11that uses the serverless job resource group and refreshes daily.CREATE MATERIALIZED VIEW myview11 MV_PROPERTIES='{ "mv_resource_group":"serverless" }' REFRESH COMPLETE ON DEMAND START WITH now() NEXT now() + INTERVAL 1 DAY AS SELECT * FROM sales;Create an elastic materialized view named
myview12that uses the serverless job resource group and can consume up to 12 ACUs.CREATE MATERIALIZED VIEW myview12 MV_PROPERTIES='{ "mv_resource_group":"serverless", "mv_refresh_hints":{"elastic_job_max_acu":"12"} }' REFRESH COMPLETE ON DEMAND START WITH now() NEXT now() + INTERVAL 1 DAY AS SELECT * FROM sales;
References
Materialized views: describes applicable scenarios and feature updates.
Create a materialized view: explains how to create materialized views and troubleshoot common errors.
Refresh materialized views: explains how to configure complete or fast refresh.
Manage materialized views: explains how to query definitions, list all materialized views, and delete materialized views.