1. 程式人生 > 其它 >PostgreSQL/Greenplum資料庫的物化檢視

PostgreSQL/Greenplum資料庫的物化檢視

技術標籤:Greenplum

一、物化檢視(MATERIALIZEDVIEW)

1、PG的版本

PostgreSQL 9.3 版本之後開始支援物化檢視。

2、與普通檢視的區別

View 檢視:虛擬,不存在實際的資料,在查詢檢視的時候其實是對檢視內的表進行查詢操作。

物化檢視:實際存在,將資料存成一張表,查詢的時候對這個表進行操作。物化檢視內的資料需要和表的資料進行同步,這就是refresh。

二、實際操作

1、實驗環境:

資料庫版本:PostgreSQL 9.6.17 及 Greenplum 6.10.1

2、初始化資料

建立表,並插入資料:

tangyibo=# create table t1 (id int ,col1 varchar(10),col2 varchar(10));
CREATE TABLE
tangyibo=# create table t2 (id int ,col3 varchar(10), col4 varchar(10), col5 varchar(10));
CREATE TABLE
tangyibo=# insert into t1 values (1,'a','b'),(2,'a','b'),(3,'a','b'),(4,'a','b'),(5,'a','b');
INSERT 0 5
tangyibo=# insert into t2 values (1,'c','d','e'),(2,'c','d','e'),(3,'c','d','e'),(4,'c','d','e'),(5,'c','d','e');
INSERT 0 5
tangyibo=# select * from t1;
 id | col1 | col2
----+------+------
  1 | a    | b
  2 | a    | b
  3 | a    | b
  4 | a    | b
  5 | a    | b
(5 rows)

tangyibo=# select * from t2;
 id | col3 | col4 | col5
----+------+------+------
  1 | c    | d    | e
  2 | c    | d    | e
  3 | c    | d    | e
  4 | c    | d    | e
  5 | c    | d    | e
(5 rows)

tangyibo=#

3、建立物化檢視

tangyibo=# CREATE MATERIALIZED VIEW IF NOT EXISTS mv_t1_t2 (t1_id,t2_id, col1,col2,col3,col4,col5) AS SELECT t1.id, t2.id, t1.col1,t1.col2,t2.col3,t2.col4,t2.col5 from t1,t2 where t1.id = t2.id WITH DATA;
SELECT 5
tangyibo=# select * from mv_t1_t2;
 t1_id | t2_id | col1 | col2 | col3 | col4 | col5
-------+-------+------+------+------+------+------
     1 |     1 | a    | b    | c    | d    | e
     2 |     2 | a    | b    | c    | d    | e
     3 |     3 | a    | b    | c    | d    | e
     4 |     4 | a    | b    | c    | d    | e
     5 |     5 | a    | b    | c    | d    | e
(5 rows)

注:在Greenplum中不支援IF NOT EXISTS;

4、重新整理物化檢視

tangyibo=# insert into t1 values (11,'x','y');
INSERT 0 1
tangyibo=# insert into t2 values (11,'x','y','z');
INSERT 0 1
tangyibo=#

對錶進行操作,不改變物化檢視中的資料。查詢物化檢視,資料沒有改變:

tangyibo=# select * from mv_t1_t2 ;
 t1_id | t2_id | col1 | col2 | col3 | col4 | col5
-------+-------+------+------+------+------+------
     1 |     1 | a    | b    | c    | d    | e
     2 |     2 | a    | b    | c    | d    | e
     3 |     3 | a    | b    | c    | d    | e
     4 |     4 | a    | b    | c    | d    | e
     5 |     5 | a    | b    | c    | d    | e
(5 rows)

tangyibo=#

(1) 全量更新:

重新整理物化檢視才能使物化檢視的資料改變。

tangyibo=# REFRESH MATERIALIZED VIEW mv_t1_t2 WITH DATA;
REFRESH MATERIALIZED VIEW
tangyibo=# select * from mv_t1_t2 ;
 t1_id | t2_id | col1 | col2 | col3 | col4 | col5
-------+-------+------+------+------+------+------
     1 |     1 | a    | b    | c    | d    | e
     2 |     2 | a    | b    | c    | d    | e
     3 |     3 | a    | b    | c    | d    | e
     4 |     4 | a    | b    | c    | d    | e
     5 |     5 | a    | b    | c    | d    | e
    11 |    11 | x    | y    | x    | y    | z
(6 rows)

tangyibo=#

(2) 增量更新

在PostgreSQL資料庫只有當物化檢視中存在unique index的時候,refresh物化檢視才能使用增量更新,加入concurrently引數。否則報錯。

tangyibo=# REFRESH MATERIALIZED VIEW CONCURRENTLY mv_t1_t2 WITH DATA;
ERROR:  cannot refresh materialized view "public.mv_t1_t2" concurrently
HINT:  Create a unique index with no WHERE clause on one or more columns of the materialized view.
tangyibo=# create unique index uidx_mv_id on mv_t1_t2 (t1_id );
CREATE INDEX
tangyibo=# insert into t1 values (12,'xx','yy');
INSERT 0 1
tangyibo=# insert into t2 values (12,'xx','yy','zz');
INSERT 0 1
tangyibo=# REFRESH MATERIALIZED VIEW CONCURRENTLY mv_t1_t2 WITH DATA;
REFRESH MATERIALIZED VIEW
tangyibo=# select * from mv_t1_t2 ;
 t1_id | t2_id | col1 | col2 | col3 | col4 | col5
-------+-------+------+------+------+------+------
     1 |     1 | a    | b    | c    | d    | e
     2 |     2 | a    | b    | c    | d    | e
     3 |     3 | a    | b    | c    | d    | e
     4 |     4 | a    | b    | c    | d    | e
     5 |     5 | a    | b    | c    | d    | e
    11 |    11 | x    | y    | x    | y    | z
    12 |    12 | xx   | yy   | xx   | yy   | zz
(7 rows)

tangyibo=#

在Greenplum資料庫中,需要唯一索引與分散式鍵相容,否在會報:UNIQUE and DISTRIBUTED RANDOMLY are incompatible

雖然在PostgreSQL資料庫中可以用WITH NO DATA重新整理物化檢視,但是在查詢時會報錯:

tangyibo=# REFRESH MATERIALIZED VIEW mv_t1_t2 WITH NO DATA;
REFRESH MATERIALIZED VIEW
tangyibo=# select * from mv_t1_t2 ;
ERROR:  materialized view "mv_t1_t2" has not been populated
HINT:  Use the REFRESH MATERIALIZED VIEW command.
tangyibo=# REFRESH MATERIALIZED VIEW mv_t1_t2 WITH DATA;
REFRESH MATERIALIZED VIEW
tangyibo=# select * from mv_t1_t2 ;
 t1_id | t2_id | col1 | col2 | col3 | col4 | col5
-------+-------+------+------+------+------+------
     1 |     1 | a    | b    | c    | d    | e
     2 |     2 | a    | b    | c    | d    | e
     3 |     3 | a    | b    | c    | d    | e
     4 |     4 | a    | b    | c    | d    | e
     5 |     5 | a    | b    | c    | d    | e
    11 |    11 | x    | y    | x    | y    | z
    12 |    12 | xx   | yy   | xx   | yy   | zz
(7 rows)

tangyibo=#