PostgreSQL 的具體化檢視(Materialized Views)提供了一種強大的機制,透過預先計算查詢結果集並將其儲存為實體資料表,從而提升查詢效能。本教學將以 DVD 租賃資料庫 為例子,指導你如何在 PostgreSQL 中建立具體化檢視。
了解具體化檢視
具體化檢視是將查詢結果集作為實體資料表儲存的快照。一般檢視是虛擬的,在每次引用時都會執行基礎查詢。與一般檢視不同,具體化檢視會一直保存資料,以在效能上提供更快的查詢速度,但需要定期重新整理。
在基礎資料變更頻率相對於查詢執行頻率較低的情況下,具體化檢視就特別有用。這也讓它們非常適合用於報表、資料倉儲以及不需要即時資料的情況。
設定 DVD 租賃資料庫
在深入研究具體化檢視之前,讓我們先設置 DVD 租賃資料庫(DVD Rental Database)。它是常用的 MySQL Sakila 範例資料庫的 PostgreSQL 版本。你可以從官方 PostgreSQL 教學網頁(PostgreSQL Sample Database)下載 DVD 租賃資料庫。
該資料庫檔案是以 ZIP 格式(dvdrental.zip)壓縮的,因此你需要將其解壓縮為 dvdrental.tar 檔案,然後將範例資料庫載入 PostgreSQL 資料庫伺服器。提取了 .tar 檔案後,請建立一個名「dvdrental」的新資料庫,並執行 pg_restore 命令將 .tar 檔案的內容填入 dvdrental 資料庫:
pg_restore -U postgres -d dvdrental D:\sampledb\postgres\dvdrental.tar
請將上述路徑替換為指向你系統上已解壓的 dvdrental.tar 檔案路徑。
你可以在 此處 查看詳細的安裝說明。
建立具體化檢視
假設我們想建立一個具體化檢視來顯示每個電影類別的總收入。以下是步驟指南:
- 連線到你的 PostgreSQL 資料庫
- 使用下列 DML 陳述式建立具體化檢視:
CREATE MATERIALIZED VIEW mv_category_revenue AS
SELECT
c.name AS category,
SUM(p.amount) AS total_revenue
FROM
category c
JOIN film_category fc ON c.category_id = fc.category_id
JOIN film f ON fc.film_id = f.film_id
JOIN inventory i ON f.film_id = i.film_id
JOIN rental r ON i.inventory_id = r.inventory_id
JOIN payment p ON r.rental_id = p.rental_id
GROUP BY
c.name;
在此範例中,我們連接 DVD 租賃資料庫中的多個資料表來計算每個電影類別的總收入。
在 Navicat For PostgreSQL (或 Navicat Premium)16 中:
- 按一下「具體化檢視」按鈕顯示具體化檢視物件清單,然後按一下物件工具列中的「+ 新增具體化檢視」以開啟檢視設計器:
- 在「定義」編輯器中輸入上述陳述式的 SELECT 部分:
- 我們可以按一下「預覽」按鈕來驗證我們的陳述式是否如預期運作:
- 按一下「儲存」按鈕建立新的具體化檢視。這將會出現一個對話方塊,提示輸入具體化檢視的名稱。我們將其命名為「mv_category_revenue」,就像上面的 CREATE MATERIALIZED VIEW 陳述式一樣:
- 按一下對話方塊中的「儲存」按鈕後,Navicat 會將新的具體化檢視名稱從「未命名」變更為我們提供的名稱。它還會將我們的具體化檢視加到左側導覽窗格中的「具體化檢視」清單中:
總結
在不要求即時資料的情況下,PostgreSQL 的具體化檢視是最佳化查詢效能的有用工具。透過預先計算和儲存複雜查詢的結果,具體化檢視可以顯著提高分析和報表工作的回應時間。在本教學中,我們學習了如何為 DVD 租賃資料庫建立具體化檢視,展示了它們在現實場景中的實際應用。