創建環境表
--創建表 CREATE TABLE teacher ( id int NOT NULL, sname varchar(100) ); CREATE TABLE student ( sid int NOT NULL, teacher_id int NOT NULL DEFAULT 0, tname varchar(100) );
INSERT into teacher(id,sname) SELECT id,id || 'lili' from generate_series(1,3) as id; INSERT INTO student (sid,teacher_id,tname) SELECT id,tea,id || 'qqqv' from generate_series(1,4) as id , generate_series(1,3) as tea;
創建普通視圖
CREATE VIEW teacher_V as SELECT id,b.tname from teacher a JOIN student b ON a.id = b.teacher_id;
創建物化視圖
CREATE MATERIALIZED VIEW teacher_M as SELECT id,b.tname from teacher a JOIN student b ON a.id = b.teacher_id;
區別分析
01,插入數據
INSERT into student VALUES (10001,2,'lipeng');
02,普通視圖查看
SELECT * from teacher_V ..... 3 3qqqv 1 4qqqv 2 4qqqv 3 4qqqv 2 lipeng
03,物化視圖查看
SELECT * from teacher_M ...... 3 3qqqv 1 4qqqv 2 4qqqv 3 4qqqv
04, 結果對比
從結果上發現了問題,我插入了值, 普通視圖能直接獲取到,但是物化視圖缺不能獲取到
05, 物化視圖如何獲取?
kingledb=# \help refresh materialized view Command: REFRESH MATERIALIZED VIEW Description: replace the contents of a materialized view Syntax: REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] name [ WITH [ NO ] DATA ]
刷新物化視圖
refresh MATERIALIZED VIEW teacher_M with no data; --查詢-- SELECT * from teacher_M > ERROR: materialized view "teacher_m" has not been populated HINT: Use the REFRESH MATERIALIZED VIEW command. 發現刷新了這個報錯了? 其實這個是no data的參數, 因為視圖進行了更改,你使用no data 刷新就會報錯,這個適用於 快速無數據刷新 如果產生了數據的話需要使用 refresh MATERIALIZED VIEW teacher_M with data; 然后 查詢 就可以了
06, 查詢執行計划
EXPLAIN SELECT * from teacher_V; Hash Join (cost=17.20..156.66 rows=3024 width=11) Hash Cond: (b.teacher_id = a.id) -> Seq Scan on student b (cost=0.00..28.90 rows=1890 width=11) -> Hash (cost=13.20..13.20 rows=320 width=4) -> Seq Scan on teacher a (cost=0.00..13.20 rows=320 width=4) EXPLAIN SELECT * from teacher_M Seq Scan on teacher_m (cost=0.00..31.40 rows=2140 width=10)
會發現這個物化視圖直接視圖抽取結果,所以每次數據是特別塊出來的,普通視圖還會去每個表查詢
07,場景分析
物化視圖適合的場景應該是對數據的實時性要求不高的場景。