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