本文介紹了PolarDB PostgreSQL版的即時物化視圖功能。
前提條件
支援的PolarDB PostgreSQL版的版本如下:
PostgreSQL 14(核心小版本14.8.11.0及以上)
PostgreSQL 11(核心小版本1.1.27及以上)
您可通過如下語句查看PolarDB PostgreSQL版的核心小版本號碼:
PostgreSQL 14
select version();
PostgreSQL 11
show polar_version;
背景資訊
物化視圖區別於普通視圖,可以直接儲存查詢的結果,在複雜查詢的情境下,使用物化視圖儲存查詢的結果可以大幅度加速查詢的效率。但物化視圖的資料不會隨著依賴表資料的變化而變化,導致使用物化視圖查詢的結果可能不是最新的。
對於這種情況,PolarDB推出了即時物化視圖的功能,即時物化視圖對於物化視圖具有以下優勢:
即時物化視圖支援語句層級更新,當依賴表進行DML(插入/刪除/更新)操作,在DML語句結束時,即時物化視圖會自動更新物化視圖內的資料,讓即時物化視圖的資料始終和依賴表的資料保持一致。
即時物化視圖最大限度的利用基表的增量資料,重新整理時無需全量執行視圖查詢,相較於頻繁的執行物化視圖重新整理,即時物化視圖的效能更好。
使用即時物化視圖可以在大幅度提升查詢效能的同時,確保查詢結果和依賴表資料的一致性。
術語
基表(Base Tables):指物化視圖定義中使用到的普通表。
增量(Delta):指基表的資料發生變化時,與物化視圖中的資料相比,增加和刪除的資料集合。
重新整理(Refresh):指物化視圖的維護操作,使得物化視圖的資料和根據視圖定義查詢當前基表獲得的資料一致。
應用增量(Apply Delta):指對即時物化視圖插入/刪除計算出來的物化視圖增量資料,以保持即時物化視圖與基表的資料一致性。
使用限制
即時物化視圖的視圖定義具有以下限制:
基表必須是普通表,不能是分區表和繼承表。
僅支援使用
INNER JOIN
,不支援其他類型的JOIN
。僅支援使用
IMMUTABLE
的函數。僅支援包含簡單的查詢、投影、
DISTINCT
、部分彙總函式的視圖定義;不支援帶有子查詢、[NOT] EXISTS
、[NOT] IN
、LIMIT
、HAVING
、DISTINCT ON
、WITH(CTE)
、ORDER BY
、視窗函數、GROUPING SETS
、CUBE
、ROLLUP
、UNION
、INTERSECT
、EXCEPT
等複雜查詢的視圖定義。使用
GROUP BY
語句時,GROUP BY
指定的分組必須出現在投影中。僅支援特定的彙總函式,即系統內建的
MIN
、MAX
、SUM
、AVG
和COUNT
函數。
效能影響
即時物化視圖大幅度提升查詢效能的同時,對基表寫入效能會有較大的影響,建議在讀多寫少的情境下使用。
即時更新物化視圖對基表寫入效能的影響程度受即時物化視圖定義、基表寫入負載、基表結構和基表索引等因素的影響,建議您在生產環境建立即時物化視圖前,在測試環境測試帶有即時物化視圖的基表的寫入效能,確認寫入效能滿足要求的情況下再在生產環境使用即時物化視圖。
以下方式有助於降低維護即時物化視圖的代價:
同一個基表上的即時物化視圖不要太多。
對基表批量寫入。例如,使用
COPY
/INSERT INTO SELECT
的方式大量匯入資料。基表都有主鍵,並且即時物化視圖定義中的投影列中包含所有基表的主鍵。
原理介紹
建立即時物化視圖
對物化視圖查詢改寫,額外計算出維護即時物化視圖所需要的隱藏列。
對基表建立Trigger,以便實現即時物化視圖的增量重新整理。
在滿足一定條件的時候,對即時物化視圖建立唯一索引,加速即時物化視圖的增量重新整理。
增量重新整理即時物化視圖
基表的資料變化觸發相應的Trigger。
通過Trigger擷取到基表的增量資料。
根據即時物化視圖的定義和當前基表的增量資料計算即時物化視圖的增量。
將計算出的增量應用到即時物化視圖上,完成即時物化視圖的增量重新整理。
刪除即時物化視圖
刪除即時物化視圖對應基表上的增量重新整理Trigger。
刪除即時物化視圖本身。
使用指南
前提條件
在需要使用即時物化視圖的資料庫中建立
polar_ivm
外掛程式。CREATE EXTENSION polar_ivm WITH SCHEMA pg_catalog;
建立即時物化視圖
CREATE MATERIALIZED VIEW table_name[ (column_name [, ...] ) ] REFRESH FAST ON COMMIT AS query [ WITH [ NO ] DATA ]
參數說明:
參數
說明
table_name
需要建立的即時物化視圖的名稱(可以被模式限定)。
column_name
新物化視圖中的一個列名。如果沒有提供列名,則會從查詢的輸出資料行名中擷取。
WITH DATA
預設選項,立刻建立完整的即時物化視圖。
WITH NO DATA
只建立出即時物化視圖的結構,但物化視圖上沒有資料,也不會在該視圖上保持即時重新整理。
查詢該即時物化視圖會報錯,直到對該即時物化視圖執行
REFRESH MATERIALIZED VIEW
命令。query
即時物化視圖的視圖定義,一個SELECT、TABLE或者VALUES命令。該查詢將在一個安全受限的操作中運行。
增量重新整理即時物化視圖
REFRESH MATERIALIZED VIEW table_name
說明其中。
table_name:表示需要重新整理的即時物化視圖的名稱(可以被模式限定)
通過
WITH DATA
方式建立的即時物化視圖通常不需要手動執行重新整理來確保視圖和基表的一致性。通過
WITH NO DATA
方式建立的即時物化視圖執行重新整理後,會通過視圖定義產生即時物化視圖的資料,並對後續基表的更改開啟即時重新整理。
刪除即時物化視圖
DROP MATERIALIZED VIEW [ IF EXISTS ] table_name [, ...] [ CASCADE | RESTRICT ]
參數說明:
參數
說明
IF EXISTS
如果該即時物化視圖不存在則不拋出一個錯誤,而是發出一個提示。
table_name
需要移除的即時物化視圖的名稱(可以是模式限定的)。
CASCADE
自動刪除依賴於該即時物化視圖的對象(例如,其他物化視圖或常規視圖),然後再刪除所有依賴於自動刪除對象的對象。
RESTRICT
如果有任何對象依賴於該即時物化視圖,則拒絕刪除該即時物化視圖。預設選擇該參數。
樣本
建立即時物化視圖的依賴外掛程式。
CREATE EXTENSION IF NOT EXISTS polar_ivm WITH SCHEMA pg_catalog ;
建立基表並匯入初始資料。
CREATE TABLE t( a INT, b VARCHAR); INSERT INTO t VALUES (1,'a'), (2,'b'), (3,'c'), (4,'d'), (5,'e');
建立即時物化視圖。
CREATE MATERIALIZED VIEW mv REFRESH FAST ON COMMIT AS SELECT max(a),min(a),b FROM t GROUP BY b;
對基表進行DML操作。
查詢即時物化視圖資料。
SELECT * FROM mv ORDER BY b;
顯示結果如下:
max | min | b -----+-----+--- 1 | 1 | a 2 | 2 | b 3 | 3 | c 4 | 4 | d 5 | 5 | e (5 rows)
結果顯示即時物化視圖的資料與基表資料保持一致。
向基表中插入新資料,查詢即時物化視圖資料。
INSERT INTO t VALUES(6,'f'); SELECT * FROM mv ORDER BY b;
顯示結果如下:
max | min | b -----+-----+--- 1 | 1 | a 2 | 2 | b 3 | 3 | c 4 | 4 | d 5 | 5 | e 6 | 6 | f (6 rows)
結果顯示即時物化視圖的資料與基表資料保持一致。
刪除基表資料,查詢即時物化視圖資料。
DELETE FROM t WHERE a = 2; SELECT * FROM mv ORDER BY b;
顯示結果如下:
max | min | b -----+-----+--- 1 | 1 | a 3 | 3 | c 4 | 4 | d 5 | 5 | e 6 | 6 | f (5 rows)
結果顯示即時物化視圖的資料與基表資料保持一致。
更新基表資料,查詢即時物化視圖資料。
UPDATE t SET a = a + 1; SELECT * FROM mv ORDER BY b;
顯示結果如下:
max | min | b -----+-----+--- 2 | 2 | a 4 | 4 | c 5 | 5 | d 6 | 6 | e 7 | 7 | f (5 rows)
結果顯示即時物化視圖的資料與基表資料保持一致。
刪除即時物化視圖。
DROP MATERIALIZED VIEW mv;