增量重新整理物化視圖(Incremental Materialized View,IVM)是物化視圖的進階形態。相較於全量重新整理需要每次重新計算整個查詢,增量重新整理僅根據基表的資料變更(INSERT、UPDATE、DELETE),准即時地更新視圖中的差異部分,從而大幅降低系統負載並提升資料的即時性。
工作原理
增量重新整理物化視圖的核心思路是:只處理變化的部分,而不是每次重新計算全部資料。
當基表發生INSERT、UPDATE、DELETE操作時,系統會自動記錄這些變更。執行增量重新整理時,僅將這些變更合并到物化視圖中。整個過程在IMCI列存節點上高效執行,無需Binlog與觸發器,對基表無鎖定影響。
FAST(增量重新整理):僅處理自上次重新整理以來的變更資料,速度快、開銷低。
COMPLETE(全量重新整理):重新計算整個查詢,適合首次初始化或資料修複。
適用範圍
使用增量重新整理物化視圖需滿足以下條件:
叢集:PolarDB MySQL版叢集需滿足以下條件:
MySQL 8.0.2,核心小版本需為8.0.2.2.35及以上。
列存索引(IMCI)參數:
參數名
預設值
要求值
說明
imci_enable_window_function
2
>= 2
需開啟支援IMCI視窗函數。
imci_enable_nci_async_pre_commit
OFF
OFF
需關閉NCI非同步預提交,避免影響增量資料一致性。
說明當前參數預設為OFF,且暫不支援調整。
imci_enable_hybrid_plan
ON
OFF
需關閉混合執行計畫,確保增量重新整理在列存索引唯讀節點執行。
說明您可以通過PolarDB控制台修改以上參數。
核心優勢
優勢 | 說明 |
低延遲資料同步 | 僅處理增量變化,避免全量掃描基表,使視圖資料以極低延遲與基表保持同步,重新整理時間從分鐘級降至秒級甚至毫秒級。 |
降低系統負載 | 大幅減少CPU、記憶體和I/O資源消耗,在基表資料量巨大而變更量相對較小的情境下效果尤為顯著。 |
無縫利用IMCI列存 | 增量計算在IMCI列存節點執行,充分利用列存的高速彙總能力。 |
加速分析查詢 | 在HTAP(混合事務/分析處理)情境下,為複雜的彙總、串連查詢提供毫秒級的響應能力。 |
自動後台維護 | 系統自動管理增量日誌(Delta表)的生命週期,無需手動幹預。 |
應用情境
預計算分析:複雜多表關聯的寬表化預先處理,避免每次查詢重複執行代價高昂的關聯操作。
報表加速:為即時數倉或BI報表提供預計算資料,通過增量重新整理將每次更新開銷降低90%以上。
計算複用:通過嵌套物化視圖實現計算複用。
即時數倉:近即時反映基表資料變化的分析型查詢。
HTAP混合負載:將頻繁更新的OLTP資料以低延遲同步到分析視圖,實現TP/AP負載分離。
使用限制
通用限制:
不支援的文法:子查詢、
UNION、ORDER BY、LIMIT、視窗函數、HAVING、ROLLUP、CTE均不支援增量重新整理。UNION ALL:暫不支援。基表要求:
基表需開啟列存索引IMCI(
polar_enable_imci = ON),且基表所有列均已被IMCI覆蓋。基表不能是普通視圖,也不能是非增量重新整理的物化視圖(允許嵌套物化視圖,但內層物化視圖需要是也是增量重新整理視圖)。
儲存開銷:
物化視圖會儲存資料副本,會佔用額外的儲存空間。
系統為維護增量物化視圖重新整理變更,也會佔用額外的儲存空間,但不會一直增長,會定期回收無效資料。
單表過濾情境限制:
基表需有顯式主鍵。
不支援
DISTINCT。
單表彙總情境限制:
基表需有顯式主鍵。
GROUP BY列需使用表的單列,不支援運算式(如GROUP BY YEAR(create_time)不支援,需改為GROUP BY create_year)。支援的彙總函式:
COUNT、SUM、AVG。暫不支援的彙總函式:
STDDEV、VARIANCE、MIN、MAX。暫不支援無
GROUP BY列的聚集。暫不支援多表彙總。
多表串連情境限制
所有基表需包含顯式主鍵。
不支援
RIGHT JOIN。串連順序需為左深樹形式,不可出現
A JOIN (B LEFT JOIN C) JOIN D的嵌套結構。每個表的ON條件需至少包含另一個表的列,不允許出現形如
A JOIN B ON B.id = 1的文法。
文法說明
CREATE MATERIALIZED VIEW mv_name
[REFRESH [COMPLETE | FAST] [ON DEMAND]]
[START WITH now()] [NEXT now() + interval 5 second]
AS SELECT ... FROM base_table;FAST:指定為增量重新整理模式,僅處理基表增量變更。COMPLETE:全量重新整理模式,每次重新計算整個查詢。ON DEMAND:按需重新整理,需手動觸發或利用後台定義的重新整理間隔進行重新整理。
操作樣本
樣本一:單表過濾(FILTER類型)
建立基表(需開啟列存索引)。
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, c3 INT) COMMENT 'COLUMNAR=1'; INSERT INTO t1 VALUES (1, 1, 1);建立增量物化視圖。
CREATE MATERIALIZED VIEW mv_filter REFRESH FAST ON DEMAND AS SELECT * FROM t1 WHERE c2 < 5;執行全量重新整理(首次建立初始資料)。
REFRESH MATERIALIZED VIEW mv_filter;基表資料變更後執行增量重新整理。
-- 基表變更 INSERT INTO t1 VALUES (2, 2, 3); DELETE FROM t1 WHERE c1 = 1; -- 增量重新整理(僅處理上述變更) REFRESH MATERIALIZED VIEW mv_filter;
樣本二:彙總統計(AGGREGATE類型)
-- 建立基表(需開啟列存索引)
CREATE TABLE orders (
order_id INT PRIMARY KEY, -- 訂單唯一ID(主鍵)
user_id INT NOT NULL, -- 使用者ID(GROUP BY 列)
amount DECIMAL(12, 2) NOT NULL, -- 訂單金額(彙總計算資料行)
order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 訂單時間(常規業務欄位)
)COMMENT 'COLUMNAR=1';
-- 彙總統計
CREATE MATERIALIZED VIEW mv_user_order_stats
REFRESH FAST ON DEMAND
AS SELECT
user_id,
COUNT(*) AS order_count,
SUM(amount * 2) AS total_amount,
AVG(CAST(amount AS INT)) AS avg_amount
FROM orders
GROUP BY user_id;支援的彙總函式:COUNT(*)、COUNT(expr)、SUM(expr)、AVG(expr)。
樣本三:多表INNER JOIN
建立基表。
CREATE TABLE t4 (id4 INT PRIMARY KEY, c2 INT, c3 VARCHAR(50)) COMMENT 'COLUMNAR=1'; CREATE TABLE t5 (id5 INT PRIMARY KEY, c2 INT, c3 VARCHAR(50)) COMMENT 'COLUMNAR=1'; CREATE TABLE t6 (id6 INT PRIMARY KEY, c2 INT, c3 VARCHAR(50)) COMMENT 'COLUMNAR=1'; INSERT INTO t4 VALUES (1, 10, 'A'), (2, 20, 'B'), (3, 30, 'C'); INSERT INTO t5 VALUES (1, 100, 'X'), (2, 200, 'Y'), (4, 400, 'Z'); INSERT INTO t6 VALUES (1, 1000, 'P'), (2, 2000, 'Q'), (3, 3000, 'R');建立多表INNER JOIN增量物化視圖。
CREATE MATERIALIZED VIEW mv_inner_with_where_on REFRESH FAST ON DEMAND AS SELECT t4.id4, t4.c2, t5.id5, t5.c2 AS t5_c2, t6.id6, t6.c2 AS t6_c2 FROM t4 INNER JOIN t5 ON t4.id4 = t5.id5 INNER JOIN t6 ON t4.id4 = t6.id6 WHERE t4.c2 > 5 AND t5.c2 > 50;執行全量重新整理並驗證。
-- 全量重新整理(首次建立初始資料) REFRESH MATERIALIZED VIEW mv_inner_with_where_on; -- 基表變更 INSERT INTO t4 VALUES (4, 40, 'D'); INSERT INTO t6 VALUES (4, 4000, 'S'); UPDATE t4 SET c2 = 15 WHERE id4 = 1; DELETE FROM t5 WHERE id5 = 4; INSERT INTO t5 VALUES (5, 400, 'W'); -- 增量重新整理 REFRESH MATERIALIZED VIEW mv_inner_with_where_on;
樣本四:LEFT JOIN
-- 建立基表(需開啟列存索引)
-- 建立產品表(被關聯表 / 右表)
CREATE TABLE products (
product_id INT PRIMARY KEY, -- 關聯鍵,必須是主鍵
product_name VARCHAR(100) NOT NULL, -- 產品名稱
price DECIMAL(10, 2) -- 其他業務欄位
) COMMENT 'COLUMNAR=1';
-- 建立訂單明細表(主表 / 左表)
CREATE TABLE order_items (
item_id INT PRIMARY KEY, -- 明細ID,必須是主鍵
order_id INT NOT NULL, -- 訂單ID
product_id INT, -- 關聯鍵,允許為NULL(因為是LEFT JOIN)
quantity INT NOT NULL, -- 購買數量
FOREIGN KEY (product_id) REFERENCES products(product_id) -- 保持外鍵約束(可選)
) COMMENT 'COLUMNAR=1';
-- LEFT JOIN
CREATE MATERIALIZED VIEW mv_order_with_product
REFRESH FAST ON DEMAND
AS SELECT
oi.item_id,
oi.order_id,
p.product_name,
oi.quantity
FROM order_items oi
LEFT JOIN products p ON oi.product_id = p.product_id;樣本五:嵌套物化視圖(計算複用)
嵌套物化視圖是指在一個增量重新整理物化視圖之上再建立另一個增量重新整理物化視圖,實現計算結果的逐層複用。例如先從基表過濾出有效資料,再對過濾結果做彙總統計,重新整理時每層僅處理各自的增量變更。
建立基表。
CREATE TABLE order_log ( order_id INT PRIMARY KEY, user_id INT, product_category VARCHAR(50), amount DECIMAL(10,2), status VARCHAR(20), created_year INT ) COMMENT 'COLUMNAR=1'; INSERT INTO order_log VALUES (1, 101, 'electronics', 299.00, 'paid', 2025), (2, 102, 'clothing', 59.90, 'paid', 2025), (3, 103, 'electronics', 499.00, 'cancelled', 2025), (4, 101, 'clothing', 120.00, 'paid', 2025), (5, 104, 'electronics', 89.00, 'paid', 2025);建立第一層增量物化視圖:過濾出已支付訂單。
CREATE MATERIALIZED VIEW mv_paid_orders REFRESH FAST ON DEMAND AS SELECT order_id, user_id, product_category, amount, created_year FROM order_log WHERE status = 'paid';執行全量重新整理建立初始資料。
REFRESH MATERIALIZED VIEW mv_paid_orders;建立第二層增量物化視圖:基於第一層視圖按品類彙總統計。
CREATE MATERIALIZED VIEW mv_category_revenue REFRESH FAST ON DEMAND AS SELECT product_category, COUNT(*) AS order_count, SUM(amount) AS total_revenue FROM mv_paid_orders GROUP BY product_category;執行全量重新整理建立初始資料。
REFRESH MATERIALIZED VIEW mv_category_revenue;基表資料變更後,按層級依次執行增量重新整理。
-- 基表新增資料 INSERT INTO order_log VALUES (6, 105, 'electronics', 199.00, 'paid', 2025), (7, 106, 'clothing', 75.00, 'cancelled', 2025); -- 按依賴順序依次重新整理:先重新整理第一層,再重新整理第二層 REFRESH MATERIALIZED VIEW mv_paid_orders; REFRESH MATERIALIZED VIEW mv_category_revenue; -- 驗證結果:order_id=7 因 status='cancelled' 被第一層過濾,不會進入第二層統計 SELECT * FROM mv_category_revenue;
嵌套物化視圖需按依賴順序從底層到頂層依次重新整理,確保每層資料一致。第一層物化視圖必須是增量重新整理類型(REFRESH FAST)。
執行增量重新整理
手動觸發重新整理:
REFRESH MATERIALIZED VIEW mv_name;增量重新整理僅處理自上次重新整理以來基表發生的變更,無需掃描全表,速度快、開銷低。
首次執行REFRESH MATERIALIZED VIEW時,系統會自動完成全量重新整理以建立初始資料,之後的重新整理均為增量重新整理。
刪除物化視圖
DROP MATERIALIZED VIEW mv_name;刪除物化視圖後,如果參數delta_mv_auto_cleanup = ON(預設),系統會自動清理對應的Delta表。
管理與監控
查看物化視圖列表
SELECT
table_name,
table_schema,
base_tables
first_refresh_time,
refresh_strategy,
last_start_time,
last_end_time
FROM mysql.view_materialized_info
WHERE refresh_strategy = 'FAST';查看所有物化視圖
SELECT * FROM mysql.view_materialized_info;監控重新整理任務隊列
SELECT * FROM information_schema.materialized_view_refresh_queue;常見問題
如何確認物化視圖是否在進行增量重新整理?
通過以下語句查看refresh_strategy列是否為FAST,並通過last_refresh_status確認最近一次重新整理結果:
SELECT table_name, refresh_strategy, last_start_time, last_end_time
FROM mysql.view_materialized_info;基表資料變更後,物化視圖何時更新?
物化視圖採用按需重新整理(ON DEMAND)模式,需要手動執行REFRESH MATERIALIZED VIEW mv_name觸發重新整理。重新整理前,視圖資料反映的是上次重新整理時的狀態。
增量重新整理期間基表是否會被鎖定?
不會。增量重新整理期間您可以繼續對基表進行正常讀寫,不受影響。
單表彙總和多表彙總是否支援增量重新整理?
單表彙總當前已支援增量重新整理。多表彙總和UNION ALL暫不支援。
增量重新整理最短重新整理周期是多少?
目前最短重新整理周期為1秒。