DatabaseMongoDBData Modeling

MongoDB Schema 設計系列 (七):Computed Pattern 計算模式優化高頻與重載查詢

作者:Simon Cho
MongoDB Schema 設計系列 (七):Computed Pattern 計算模式優化高頻與重載查詢

Computed Pattern (計算模式) 是用來解決很頻繁使用,但 Loading 很重或運算較久的 query 所造成的效能與效能瓶頸問題。

作法非常簡單直覺:就是預先算好結果並直接儲存起來,用寫入時的輕微代價換取讀取時的極致效能

Computed Pattern Database Concept: 預先計算以避開 CPU 開銷


常見的 Computed Pattern 三大應用情境

到底怎麼樣的運算才算 Loading 重或運算較久,而適合套用 Computed Pattern 呢?以下介紹三種實戰最常見的類型:

1. 數學/統計聚合運算 (Mathematical Operations)

例如:在後台或首頁有個 query 需要頻繁回傳「最新 100 筆感測器資料的平均值」。

如果採用傳統方式,每次讀取請求進來時,資料庫的步驟是:

  1. 查詢所有相關資料。
  2. 按照時間欄位排序。
  3. 取得最新 100 筆資料。
  4. 在記憶體中進行加總並除以 100 計算平均。

這個查詢每一次都會造成大量的硬碟 I/O 以及 CPU 排序與加總開銷。如果我們套用 Computed Pattern,在每一次「寫入新感測資料」時,就在背景或 Data Access Layer 順便算好最新的平均值並直接更新到一個快取 document 內。這樣讀取時只需要直接 GET 該數值,便能省去每一次的重複計算。

2. 讀取扇出優化 (Fan Out On Read)

這是指一個查詢需要同時從多個不同的來源 (多個 collections 或 documents) 抓取資料再進行運算與拼裝,導致使用者等待很久的問題。

影音平台的頻道訂閱為例:

  • Fan Out On Read (讀取時計算):每次使用者登入首頁時,系統才去撈取他訂閱的 50 個頻道的最新影片,並將這 50 個影片依照上架時間合併排序。這會造成巨大的多表查詢負擔與時間延遲。
  • Fan Out On Write (套用 Computed Pattern):每當某個頻道發布新影片時,系統主動將該影片的 ID 與基本資料寫入到所有「訂閱該頻道的使用者」的「最新訂閱影片 Inbox 列表」中。當訂閱者登入首頁時,直接從他個人的 Inbox 文件撈取資料,達成秒開首頁的極致體驗。

3. 層級累加運算 (Roll Up Operation)

Roll Up Operation 是指將資料從不同的細緻度 (Granularity) 來進行歸納與加總

例如:假設你在全台灣經營自有品牌連鎖店。你可以看:

  • 各分店月營收
  • 各縣市月總營收
  • 北中南區域月營收
  • 全台總月營收

除了最底層的「各分店營收」是原始交易紀錄外,其餘縣市、區域、全台營收全部都是由下方層級的營收累加加總上來的。如果每次管理者看儀表板時資料庫都要當場執行 Group & Sum 累加,速度會極慢。

透過 Computed Pattern,我們可以在每日結帳時,自動將分店營收往上計算,並直接將累加結果儲存至 county_revenueregion_revenuenational_revenue collection。管理者讀取儀表板時便能瞬間載入。


優點與缺點權衡

  • 優點:能夠極大地節省資料庫的 CPU 計算時間、降低磁碟 I/O,並將讀取回應時間縮短至毫秒級。
  • 缺點這是一個非常容易被濫用的 Pattern。因為它實作起來太直覺簡單,且不像 Duplication/Embedding 那樣有嚴重且複雜的資料雙向一致性問題(我們只需要在資料寫入或更新時,單向去計算並覆寫結果)。

[!WARNING] 請在確認該查詢的讀寫比例極高 (讀極多、寫極少),且實時計算確實已造成資料庫明顯 Loading 之後再行導入,避免讓系統的寫入邏輯變得過於臃腫。

← 返回所有故事