PostgreSQL JSONB Hot Predicate Anti-pattern¶
概念概覽
核心規則¶
核心知識¶
核心規則¶
查詢 hot path 上的 predicate 欄位(高頻 WHERE 條件)不應存放於 JSONB,即使 PostgreSQL 支援 JSONB expression index。
原因¶
- JSONB expression index 有效,但 selectivity 和 vacuum 行為劣於原生欄位
- 25M snapshot path 場景下,JSONB predicate 查詢不可接受(成本過高)
season_id這類業務核心 predicate 若放 JSONB,schema 演進與 query planner 優化空間都受限
判斷標準¶
本案例¶
inventory 表缺少 season_id 和 item_secondary_type 原生欄位,導致 AUTO_CONVERT snapshot 查詢模型與實作完全對不上。修正路徑:加原生欄位 + 補 index,而非補 JSONB expression index。
經驗教訓¶
-
PostgreSQL 可對 JSONB 做 expression index,但這不代表 hot predicate 應該放 JSONB
-
schema 設計時 season_id 這類業務核心維度應從一開始就是原生欄位
-
查詢模型(設計文檔)與實作 schema 對不上,通常根因是早期 schema 決策不完整
常見陷阱¶
-
以「JSONB 有 expression index 支援」為由把 season_id 留在 metadata JSONB
-
在 25M+ 行的 snapshot 表上用 JSONB predicate 掃描而不加原生欄位
最佳實踐¶
-
新增原生欄位 season_id(NOT NULL,有預設值或 backfill)
-
確認 item_id 語義粒度是否能唯一決定 pack type,再決定是否需要 item_secondary_type 欄位
相關概念¶
來源 Sessions¶
| 日期 | Session | 貢獻摘要 |
|---|---|---|
| 2026-03-31 | c903e4ed-15e4-4a39-b7b8-30b428e38075 | 確立 hot predicate(如 season_id)不應放 JSONB 的判斷標準,以 25M snapshot path 為具體門檻佐證 |