Materialized views store precomputed query results to speed up complex queries and simplify extract, transform, and load (ETL) pipelines. To keep the results current, you set a refresh policy and a refresh trigger when you create the view.
Refresh policies
AnalyticDB for MySQL supports two refresh policies. Choose one based on the write mode of your base tables, query complexity, and freshness requirements.
| Refresh policy | How it works | Best for | Advantages | Limitations |
|---|---|---|---|---|
| Complete refresh | Scans all data in all base table partitions and overwrites the materialized view with the full query result. | Batch processing: T+1 daily loads, hourly updates, or small datasets where minute-level latency is acceptable. | Supports all SQL statements in the materialized view query. | Updates the entire dataset in batches only. |
| Fast refresh | Rewrites the query to scan only changed data in base tables and incrementally updates the materialized view. | Real-time analytics: continuous data ingestion, live reports or ETL pipelines, second-level latency requirements. | Low compute overhead on incremental data. Lower development and maintenance costs compared to stream processing. | Restricted SQL, version, and base table requirements. No manual refresh or overwrite-triggered refresh. |
Decision guide:
If your base tables receive periodic batch loads and minute-level staleness is acceptable, use complete refresh.
If your base tables receive continuous inserts and you need second-level freshness, use fast refresh. First verify that your query and cluster version meet the fast refresh limitations.
Refresh triggers
A refresh trigger controls *when* a refresh runs. Define a trigger when you create the materialized view.
| Trigger | SQL clause | Behavior | Best for |
|---|---|---|---|
| Manual | ON DEMAND (no NEXT clause) | No automatic refresh. Run REFRESH MATERIALIZED VIEW manually. | Low consistency requirements or infrequently changing data. |
| Scheduled | ON DEMAND with NEXT clause | Refreshes at a fixed interval. If the previous refresh is still running when the next interval arrives, the pending refresh is skipped. | Periodically changing data, such as daily or weekly transaction records. |
| Overwrite-triggered | ON OVERWRITE | Refreshes when a base table is overwritten with INSERT OVERWRITE. | High data freshness and consistency requirements. |
If you do not specify a trigger, ON DEMAND (manual refresh) is the default.Policy and trigger compatibility
Not every trigger works with every refresh policy.
| Refresh policy | Manual | Scheduled | Overwrite-triggered |
|---|---|---|---|
| Complete refresh | Supported | Supported | Supported |
| Fast refresh | Not supported | Supported | Not supported |
Create materialized views with refresh settings
The following examples use three base tables: customer, sales, and product.
/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */ -- Set the table engine to XUANWU.
CREATE TABLE customer (
customer_id INT PRIMARY KEY,
customer_name VARCHAR(255),
is_vip Boolean
);
/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */ -- Set the table engine to XUANWU.
CREATE TABLE sales (
sale_id INT PRIMARY KEY,
product_id INT,
customer_id INT,
price DECIMAL(10, 2),
quantity INT,
sale_date TIMESTAMP
);
/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */ -- Set the table engine to XUANWU.
CREATE TABLE product (
product_id INT PRIMARY KEY,
product_name VARCHAR,
category_id INT,
unit_price DECIMAL(10, 2),
stock_quantity INT
);Complete refresh examples
Manual refresh (no trigger configured):
CREATE MATERIALIZED VIEW compl_mv1
REFRESH COMPLETE
AS
SELECT * FROM customer;The view is not automatically refreshed. Run REFRESH MATERIALIZED VIEW compl_mv1; to refresh it manually.
Scheduled refresh (daily at 02:00):
CREATE MATERIALIZED VIEW compl_mv2
REFRESH COMPLETE ON DEMAND
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 * FROM customer;Overwrite-triggered refresh:
CREATE MATERIALIZED VIEW compl_mv3
REFRESH COMPLETE ON OVERWRITE
AS
SELECT * FROM customer;The view refreshes automatically whenever the customer table is overwritten with INSERT OVERWRITE.
Fast refresh examples
Enable binary logging
Before you create a fast-refresh materialized view, enable binary logging for both the cluster and the base tables.
SET ADB_CONFIG BINLOG_ENABLE=true; --For clusters earlier than V3.2.0.0, run this statement manually. For V3.2.0.0 or later, binary logging is automatically enabled.
ALTER TABLE customer binlog=true;
ALTER TABLE sales binlog=true;
ALTER TABLE product binlog=true;INSERT OVERWRITE INTOandTRUNCATEon binlog-enabled tables are only supported in clusters V3.2.0.0 or later.While a fast-refresh materialized view exists, binary logging cannot be disabled on its base tables.
After deleting a fast-refresh materialized view, disable binary logging with
SET ADB_CONFIG BINLOG_ENABLE=false;andALTER TABLE <table_name> binlog=false;.
Single-table views
No aggregate function -- refresh every 10 seconds:
CREATE MATERIALIZED VIEW fast_mv1
REFRESH FAST NEXT now() + INTERVAL 10 second
AS
SELECT sale_id, sale_date, price
FROM sales
WHERE price > 10;Aggregate with GROUP BY -- refresh every 5 seconds:
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;Aggregate without GROUP BY -- refresh every 1 minute:
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;Multi-table views
No aggregate function -- refresh every 5 seconds:
CREATE MATERIALIZED VIEW fast_mv4
REFRESH FAST NEXT now() + INTERVAL 5 second
AS
SELECT
c.customer_id,
c.customer_name,
p.product_id,
s.sale_id,
(s.price * s.quantity) AS revenue
FROM
sales s
JOIN
customer c ON s.customer_id = c.customer_id
JOIN
product p ON s.product_id = p.product_id;Aggregate with GROUP BY -- refresh every 10 seconds:
CREATE MATERIALIZED VIEW fast_mv5
REFRESH FAST NEXT now() + INTERVAL 10 second
AS
SELECT
s.sale_id,
c.customer_name,
p.product_name,
COUNT(*) AS cnt,
SUM(s.price * s.quantity) AS revenue,
SUM(p.unit_price) AS sum_p
FROM
sales s
JOIN
(SELECT customer_id, customer_name FROM customer) c ON c.customer_id = s.customer_id
JOIN
(SELECT * FROM product WHERE stock_quantity > 0) p ON p.product_id = s.product_id
GROUP BY
s.sale_id, c.customer_name, p.product_name;Fast refresh limitations
Review these limitations before you create a fast-refresh materialized view. If the view query does not meet these requirements, the CREATE MATERIALIZED VIEW statement returns an error.
Version requirements
| Requirement | Minimum version |
|---|---|
| Partitioned base tables | V3.2.3.0 |
INSERT OVERWRITE and TRUNCATE on base tables | V3.2.3.1 |
Refresh interval
| Constraint | Value |
|---|---|
| Supported trigger | Scheduled refresh only (no manual refresh) |
| Minimum interval | 5 seconds |
| Maximum interval | 5 minutes |
Query restrictions
The materialized view must provide the same data as the query results on base tables and must support all DML operations.
Expressions that produce non-deterministic values (such as
now()andrand()) are not allowed in query conditions.Window functions, sorting operations, and set operations (
UNION,EXCEPT,INTERSECT) are not supported.The
HAVINGkeyword is not supported with aggregate functions.
Supported aggregate functions
| Function | DML restrictions on base tables | Type restrictions |
|---|---|---|
COUNT() | None | None |
SUM() | None | None |
AVG() | None | DECIMAL type not supported |
MAX() | INSERT only. DELETE, UPDATE, REPLACE, and INSERT ON DUPLICATE KEY UPDATE are not allowed. | None |
MIN() | INSERT only. DELETE, UPDATE, REPLACE, and INSERT ON DUPLICATE KEY UPDATE are not allowed. | None |
APPROX_DISTINCT() | INSERT only. DELETE, UPDATE, REPLACE, and INSERT ON DUPLICATE KEY UPDATE are not allowed. | None |
COUNT(DISTINCT) | INSERT only. DELETE, UPDATE, REPLACE, and INSERT ON DUPLICATE KEY UPDATE are not allowed. | INTEGER type only |
Aggregate functions other than COUNT(DISTINCT) do not support the DISTINCT keyword.
Multi-table join restrictions
| Constraint | Value |
|---|---|
| Supported join type | INNER JOIN only |
| Maximum base tables per view | 5 (default) |
| Join field requirements | Must be original table columns, must serve as indexes, and must share the same data type |
Manually refresh a materialized view
For materialized views created with ON DEMAND and no NEXT clause, run the following statement to trigger a refresh:
REFRESH MATERIALIZED VIEW <mv_name>;The refresh job runs in the background. You can continue performing other operations while it completes. When finished, the system returns Query OK or Success.
Query refresh records
Automatic refresh records
Query the information_schema.mv_auto_refresh_jobs table to retrieve automatic refresh history, including start time, end time, status, and query ID. For field descriptions, see Manage materialized views.
SELECT * FROM information_schema.mv_auto_refresh_jobs WHERE mv_name = '<mv_name>';Manual refresh records
Two methods are available:
SQL audit (last 30 days): On the XIHE SQL Audit tab, enter
REFRESH MATERIALIZED VIEW <mv_name>in the Keyword field. The results show the time, duration, IP address, and database account for each manual refresh.Enable the SQL audit feature separately. SQL operations performed before enablement are not included in audit logs.

SQL diagnostics and optimization (last 14 days): On the SQL Diagnostics and Optimization tab, enter the materialized view name (for example,
compl_mv1). The results show the start time, database account, duration, and query ID for both manual and automatic refresh records.
Stop a running refresh job
To stop a long-running refresh job, contact technical support.
Running KILL PROCESS <process_id>; stops the current refresh job, but the next scheduled or overwrite-triggered refresh still runs as configured.References
Create a materialized view -- Step-by-step guide to creating materialized views.
CREATE MATERIALIZED VIEW -- Full SQL syntax reference.
Manage materialized views -- Query definitions, view refresh records, modify views, and delete views.