理解 Materialized View:初學者指南

Published February 26, 2025 by 徐培鈞
資料庫

在資料庫管理中,查詢效能是一個重要的考量因素。

當資料表的數據量龐大,且需要頻繁執行複雜的查詢時,直接從原始表查詢可能會導致效能下降。

這時候,「物化檢視(Materialized View)」就成為提升查詢效能的利器。

它能夠將查詢結果預先儲存,以減少查詢時間,提高系統的整體效能。

本文將帶領初學者深入了解物化檢視的概念、優勢、使用場景,以及與一般檢視(View)的差異。


什麼是「物化」?(Materialized 的概念)

在計算機科學中,「物化(Materialization)」是一種預先計算並存儲結果的技術,它的目標是避免重複計算,提升效能。

想像一下,你每天早上都要從家裡走到超市買早餐,如果你每次都從零開始走過去,這就是即時計算(On-the-fly computation),每次需要結果時都要重新執行整個過程。

但如果你提前買好一週的早餐放在家裡,當你需要早餐時,只需從冰箱拿出來吃,這就是物化計算(Materialized Computation)——結果已經準備好,不用再重複計算。

物化的核心概念就是這樣:

與其每次都從頭計算,不如先計算好並存起來,後續直接讀取結果,節省時間與資源。

什麼是「物化計算」(Materialized Computation)?

當我們談論「計算」時,通常有兩種方式來處理數據:

  1. 即時計算(On-the-fly Computation)
    • 每次需要結果時,從頭開始執行計算。
    • 例如:每次查詢一個數據時,系統都要重新計算總和、平均值、排序等。
    • 優點:始終是最新的結果。
    • 缺點:當數據量很大、計算很複雜時,查詢會變慢。
  2. 物化計算(Materialized Computation)
    • 先計算好並存下來,後續需要時直接讀取存好的結果。
    • 例如:如果你每天都需要統計銷售報表,那麼不必每天重新計算所有交易數據,而是在每天結束時預先計算好報表並存起來,後續查詢時就直接讀取這個報表。
    • 優點:讀取速度快,減少重複計算的負擔。
    • 缺點:數據可能不是即時更新的,需要定期刷新。

舉個更直觀的例子:

  • 即時計算: 你每次打開導航 APP,都讓系統重新計算你從家到公司的最佳路線。
  • 物化計算: 你事先查好家到公司的路線,並將結果存下來,之後直接查看,不用重新計算。

這種 「先算好、存起來、之後直接用」 的方式就是 物化計算(Materialized Computation),它的主要目標是提升查詢速度、減少系統負擔

物化計算的應用場景

物化計算廣泛應用於各種計算密集型場景,例如:

  1. 數據庫查詢加速
    • 例如:統計「每月銷售總額」,如果每次查詢都重新計算,會很慢;如果每天結束時先計算好總額,查詢時就能快速讀取結果。
  2. 快取(Caching)技術
    • 例如:當你打開一個網站,它可能會先顯示一個快取的頁面,而不是每次都從頭生成,這樣可以提升載入速度。
  3. 商業智慧(BI)和數據分析
    • 例如:報表生成時,系統可以預先計算一些數據,使用者查詢時就不需要即時計算,提升查詢效能。

這個概念是 Materialized View(物化檢視) 的基礎。

因為 Materialized View 就是資料庫應用物化計算來提升查詢效能的一種方式。


什麼是 View(檢視)?

在資料庫的世界裡,View(檢視) 就像是一個「查詢的快捷方式」。它本質上是一個預先寫好的 SQL 查詢的封裝,讓我們可以像查詢一張表一樣使用它,但它本身並不存放數據。

舉個例子:View 就像是一張即時產生的清單

想像你在一家公司擔任人資主管,每天都要查詢「IT 部門的員工名單」。如果你每次都要寫這個查詢,會很麻煩:

SELECT id, name, salary 
FROM employees 
WHERE department = 'IT';

於是,你建立了一個 View:

CREATE VIEW it_employees AS
SELECT id, name, salary 
FROM employees 
WHERE department = 'IT';

以後,你只需要簡單地查詢:

SELECT * FROM it_employees;

這就像是你在 Excel 建立了一個篩選條件,每次打開這個篩選,都能即時看到最新的 IT 部門員工名單。但 View 本身不存數據,每次你查詢時,它都會重新去資料表抓最新的資料

View 的優勢

  1. 簡化查詢
    • 讓複雜的 SQL 變得簡單,避免每次都要寫長串的 JOIN 或篩選條件。
  2. 提高安全性
    • 可以讓特定使用者只能存取部分欄位(例如:讓普通員工只能看到 idname,不能看到 salary)。
  3. 保持數據即時更新
    • View 不存數據,所以當原始資料表更新時,View 也會顯示最新的資料。

View 有什麼缺點?

雖然 View 很方便,但它有一個致命的問題——當查詢變得複雜、數據量變大時,它的查詢效能會變得很差

因為 View 每次查詢時都要重新去資料表抓數據並執行 SQL,這樣會消耗大量計算資源。這時候,View 的便利性反而變成了負擔。


Materialized View(物化檢視)的命名由來

我們已經知道,View 每次查詢時都會重新執行 SQL,這可能會變慢

那麼,有沒有辦法讓 View 的查詢變快呢?這就是 Materialized View(物化檢視) 出現的原因。

為什麼叫「Materialized View」?

🔵 「Materialized」這個詞的意思是「實體化」或「物質化」,代表它不只是虛擬的,而是「真的存在」的。

這個名字其實很好理解——普通 View 只是一個 SQL 查詢的「快捷方式」,每次查詢時都要重新計算。

Materialized View 的概念就是:「我們能不能先把查詢結果存起來,之後直接讀取?」

這就像是:

  • 普通 View = 每次都現煮咖啡(每次重新執行 SQL 查詢)。
  • Materialized View = 先煮好一壺咖啡,之後倒出來喝(預先計算好,之後直接讀取結果)。

這樣,查詢時就能省掉重新計算的時間,速度快很多!

為什麼不是叫「Materialized Table」?

有人可能會問:「既然 Materialized View 會把結果存起來,那為什麼不直接叫它Materialized Table(物化表)?」

原因很簡單:

  1. 它的數據還是來自 SQL 查詢,而不是獨立的表。
    • Materialized View 只是查詢結果的快取,不是全新的表
    • 如果原始表更新了,Materialized View 並不會自動更新,而是要手動「刷新」它的內容。
  2. 它保留了 View 的特性(可以像查詢普通表一樣使用,但不需要重新計算)。
    • 它不像 Table 那樣允許隨時 INSERTUPDATEDELETE,它是根據 SQL 查詢結果來決定內容的。

所以,Materialized View 仍然叫 View,而不是 Table,因為它是 View 的加強版,而不是完全獨立的表。

普通 View vs. Materialized View(物化檢視)

普通 View❌ 不存
Materialized View✅ 存結果
普通 View🚀 依賴基礎表,可能較慢
Materialized View⚡ 快,因為結果已存儲
普通 View📡 即時更新
Materialized View🛠 需要手動 REFRESH
普通 View🔍 需要即時數據
Materialized View📊 頻繁查詢但數據變動不大的場景

簡單來說:

  • View 是查詢的「快捷方式」,但每次查詢都要重新計算。
  • Materialized View 是「存好的查詢結果」,查詢時直接讀取,速度快,但需要手動更新。

這就是為什麼 Materialized View 仍然叫 View,而不是 Table——它保留了 View 的使用方式,但多了一個「存起來」的特性。

所以,你可以這樣記住:

「View 是 SQL 的捷徑,而 Materialized View 則是 SQL 查詢的快取!」

這樣的設計,使 Materialized View 在資料分析、報表、商業智慧(BI)等場景中特別有用,因為這些場景需要頻繁查詢固定格式的數據,但又不希望查詢過慢。

現在,你已經完全理解 Materialized View 為什麼叫這個名字了!🚀


如何建立與更新 Materialized View?

在 SQL 中,建立 Materialized View 的語法與普通 View 類似,但關鍵的不同點是它會存儲數據

📌 建立 Materialized View

CREATE MATERIALIZED VIEW monthly_sales AS
SELECT 
    DATE_TRUNC('month', sale_date) AS month,
    SUM(amount) AS total_sales
FROM sales
GROUP BY DATE_TRUNC('month', sale_date);

這個 Materialized View 會存儲「每月銷售總額」,讓查詢時不需要重新計算。

📌 更新(刷新)Materialized View 由於 Materialized View 不會自動更新,因此當數據變更時,需要手動或定期刷新:

REFRESH MATERIALIZED VIEW monthly_sales;

如果你的資料庫支援,可以使用:

REFRESH MATERIALIZED VIEW monthly_sales WITH DATA;

這樣會強制刷新數據,使查詢結果保持最新


為什麼要使用 Materialized View?

我們已經知道,Materialized View(物化檢視)的核心概念是先把查詢結果存起來,讓後續的查詢更快。但具體來說,它能帶來哪些好處呢?這裡有幾個關鍵優勢:

查詢速度大幅提升

想像你每次要計算公司整年的銷售額,系統都要重新把數百萬筆交易記錄加總,這樣查詢速度會變得非常慢。

但如果我們事先計算好,直接存起來,查詢時就能瞬間拿到結果!

這正是 Materialized View 最大的優勢:預先計算好查詢結果,存起來,讓後續查詢變快

普通 View 每次查詢時都要重新計算,但 Materialized View 直接從存好的數據取值,效能大幅提升,特別適合需要頻繁查詢的場景。

📌 舉例

  • 普通 View: 每次查詢時,系統都要重新跑 SQL:
SELECT SUM(amount) FROM sales WHERE date >= '2023-01-01';
  • Materialized View: 預先計算並存起來,之後查詢時就直接讀取:
SELECT * FROM yearly_sales_summary;
  • 結果立刻就能拿到!

減少資料庫的負擔

如果每個人都不斷查詢同樣的數據,會讓資料庫變得超級忙,影響整個系統效能!

當大量使用者頻繁查詢相同的數據時,系統需要重複計算相同的結果,這會增加 CPU、記憶體和 I/O 負擔。

Materialized View 可以大幅減少這種負擔,因為:

  • 事先計算好的結果被存起來,查詢時不需要重新運算。
  • 減少了對原始表的存取,降低資料庫負載,讓系統更流暢。

📌 適用場景

  • 電商網站的熱門商品排行:不用每次重新計算,而是直接讀取 Materialized View。
  • 金融數據分析:避免每次查詢都重新計算整年的交易數據。

特別適合複雜的 SQL 查詢

當 SQL 查詢涉及 JOIN、GROUP BY、SUM、AVG 等運算時,執行時間會變得很長。

有些 SQL 查詢又長又複雜,每次執行都要花費大量時間,特別是:

  • JOIN 多張表(跨部門資料統計)。
  • GROUP BY 聚合計算(統計銷售額、客戶數等)。
  • 排序(ORDER BY)(找出前 100 名 VIP 客戶)。

這些查詢通常執行起來會很慢,但如果我們用 Materialized View 事先算好並存起來,就能在後續查詢時直接取用結果,讓查詢效能變得更高。

📌 適用場景

  • 電商平台的「每月銷售報表」(先存好,不用每次都重新計算)。
  • 社群網站的「熱門文章排行」(不用每次計算點擊數,直接讀 Materialized View)。

可以定期刷新數據

雖然 Materialized View 不會即時更新,但我們可以設定「手動或自動刷新」,確保數據保持最新!

與普通 View 不同,Materialized View 的數據不會隨著原始表變更而即時更新,這是它的一大特點。

但這並不代表數據永遠不會更新,我們可以根據需求手動或定期刷新,以確保數據是最新的。

📌 如何刷新 Materialized View? 當原始數據表有變更時,可以手動執行:

REFRESH MATERIALIZED VIEW monthly_sales;

有些資料庫(如 PostgreSQL)支援:

REFRESH MATERIALIZED VIEW monthly_sales WITH DATA;

這樣就能確保數據不會過時!

📌 適用場景

  • 每日、每週報表(例如「昨日銷售總額」,每天凌晨刷新一次)。
  • 熱門關鍵字分析(每小時更新一次)。

結論

Materialized View(物化檢視)是一種強大的技術,它的核心概念是:

先把查詢結果存起來,後續查詢時直接讀取,減少重複計算,提高效能。
適用於需要頻繁查詢但變動不大的數據,如銷售報表、財務報告、商業智慧(BI)分析等。
可以手動或定期刷新,確保數據保持最新。

希望這篇文章能幫助你理解 Materialized View,讓你在設計資料庫時更有效率!🚀