我們知道,視圖是表示基礎表的數(shù)據(jù)的虛擬表。簡單的視圖也可以是可更新的。PostgreSQL 將視圖概念擴展到更高級,允許視
圖物理地存儲數(shù)據(jù),
這種視圖稱為物化視圖(materialized views)。物化視圖將開銷非常大的復雜的查詢結果進行緩存,然后允許您定期刷新此結
果。
一、創(chuàng)建物化視圖
create materialized view view_name as query_sql with [no] data;
with data: 創(chuàng)建物化視圖后,視圖不可查詢(因為無數(shù)據(jù))
with no data: 創(chuàng)建物化視圖后,視圖可查詢數(shù)據(jù)
二、刷新物化視圖的數(shù)據(jù)
(1)、即將數(shù)據(jù)加載到物化視圖中。
refresh materialized view view_name;
(2)、刷新物化視圖的數(shù)據(jù)時,或鎖定整張表(在大數(shù)據(jù)量的情況下比較久,會導致其它查詢語句無法執(zhí)行)。為了避免此種情
況,可使用concurrently選項。
refresh materialized view concurrently view_name;
注:使用 concurrently 選項,PostgreSQL將創(chuàng)建物化視圖的臨時更新版本,比較更新版本和原視圖兩個版本,并僅對差異部分
執(zhí)行 insert 和 update。
這樣就可以在更新時對物化視圖進行查詢。使用 concurrently 選項的一個要求是:物化視圖必須具有 unique 索引。注意
CONCURRENTLY 選項只能在 PostgreSQL 9.4 及以上版本中使用。
create unique index index_name on view_name (列名1,列名2...);
三、刪除物化視圖
drop materialized view [if exists] view_name;
案例:
創(chuàng)建物化視圖:
select * from payment;
select * from rental;
select * from inventory;
select * from film;
select * from film_category;
select * from category;
一、創(chuàng)建物化視圖:
create materialized view rental_by_category as
select
cy.name,
sum(pt.amount) as sum_amount
from payment pt
inner join rental rl on pt.rental_id=rl.rental_id
inner join inventory iy on rl.inventory_id=iy.inventory_id
inner join film fm on iy.film_id=fm.film_id
inner join film_category fy on fm.film_id=fy.film_id
inner join category cy on fy.category_id=cy.category_id
group by cy.name
order by sum_amount
with no data;
select * from rental_by_category;
結果:因為創(chuàng)建物化視圖使用了with no data因此查詢時提示報錯
> 錯誤: 物化視圖 "rental_by_category"未被初始化
二、刷新物化視圖數(shù)據(jù):
refresh materialized view rental_by_category;
select * from rental_by_category;
三、使用concurrently選項刷新物化視圖:
前提必須先為物化視圖創(chuàng)建唯一索引
create unique index inx_rental_by_category on rental_by_category (name);
refresh materialized view concurrently rental_by_category;
select * from rental_by_category;

payment源表.png

rental源表.png

inventory源表.png

film源表.png

film_category源表.png

category源表.png