postgres中的視圖和物化視圖


視圖和物化視圖區別

postgres中的視圖和mysql中的視圖是一樣的,在查詢的時候進行掃描子表的操作,而物化視圖則是實實在在地將數據存成一張表。說說版本,物化視圖是在9.3 之后才有的邏輯。

比較下視圖和物化視圖的性能

創建兩個表

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)
);

創建一個視圖

CREATE OR REPLACE VIEW student_view AS
SELECT  *
   FROM student
   LEFT JOIN teacher 
   ON student.teacher_id = teacher.id;

創建一個物化視圖

CREATE MATERIALIZED VIEW student_view_m AS
SELECT  *
   FROM student
   LEFT JOIN teacher 
   ON student.teacher_id = teacher.id;

進行查詢explain:

master=> explain select * from student_view;
                               QUERY PLAN
------------------------------------------------------------------------
 Hash Right Join  (cost=16.98..48.34 rows=496 width=448)
   Hash Cond: (teacher.id = student.teacher_id)
   ->  Seq Scan on teacher  (cost=0.00..13.20 rows=320 width=222)
   ->  Hash  (cost=13.10..13.10 rows=310 width=226)
         ->  Seq Scan on student  (cost=0.00..13.10 rows=310 width=226)
(5 rows)

master=> explain select * from student_view_m;
                            QUERY PLAN
-------------------------------------------------------------------
 Seq Scan on student_view_m  (cost=0.00..11.70 rows=170 width=448)
(1 row)

可以看出,student_view去每個表中進行查詢,而student_view_m 直接去視圖表查詢,而物化視圖的查詢效率確確實實高於視圖不少。

物化視圖的數據填充

物化視圖既然是一個實實在在存在的表,它就需要有數據填充過程,數據填充的命令是REFRESH MATERIALIZED VIEW

master=> \h REFRESH
Command:     REFRESH MATERIALIZED VIEW
Description: replace the contents of a materialized view
Syntax:
REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] name
    [ WITH [ NO ] DATA ]

這里有個注意的,如果你的psql是9.3的,那么你查看幫助文檔就只會看到:

master=> \h REFRESH
Command:     REFRESH MATERIALIZED VIEW
Description: replace the contents of a materialized view
Syntax:
REFRESH MATERIALIZED VIEW name
    [ WITH [ NO ] DATA ]

這里就引入說postgres的更新數據庫有兩種方式,一種是全量更新,一種是增量更新,增量更新是在REFRESH的時候增加一個CONCURRENTLY參數。而增量更新是9.4才加入的操作。

那么哪種更新快呢?答案是全量更新,增量更新做的操作是將當前視圖表中的數據和query中的數據做一個join操作,然后才將差量做填充。

但是全量更新會阻塞select操作,就是說,你全量更新的過程中,所有對視圖的select操作都會被阻塞,而增量更新卻不會這樣。

物化視圖適合什么

物化視圖適合的場景應該是對數據的實時性要求不高的場景。

我的項目中遇到的情況是提出問題,立刻就要在問題表中看到我提出的問題,雖然可以做觸發器來當insert的時候觸發增量更新,但是,當數據量大的時候,增量更新的速度確實不能承受。所以,在這種情況下,還是放棄物化視圖,從索引方面多考慮考慮。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM