DynamoDB 中的 GSI vs LSI
全域次要索引(GSI)和區域次要索引(LSI)都讓你能以一個非資料表索引鍵的屬性來 Query。但它們並不能互換——這些差異決定了一個模式該用哪一個。
DynamoDB 中 GSI 和 LSI 有什麼差別?
全域次要索引可以用任何頂層純量屬性(String、Number 或 Binary)當它的分割區索引鍵、擁有自己的容量,並且可以隨時新增——但它只提供最終一致讀取。區域次要索引沿用資料表相同的分割區索引鍵、搭配不同的排序索引鍵,支援強一致讀取並共用資料表的容量,但必須在建立資料表時一起建立。
重要的差異
| GSI | LSI | |
|---|---|---|
| 分割區索引鍵 | 任何純量(S/N/B) | 與資料表相同 |
| 排序索引鍵 | 任何純量(S/N/B) | 任何純量(S/N/B) |
| 何時建立 | 隨時 | 僅建立資料表時 |
| 一致性 | 僅最終一致 | 可用強一致 |
| 容量 | 自己的 | 共用資料表的 |
| 寫入傳播 | 非同步(最終一致) | 同步(原子) |
| 每張表最多 | 20(預設,可調高) | 5(硬限制) |
| 10 GB 分割區上限 | 否 | 是(每個 PK) |
一條經驗法則
- 需要一個不同的(例如以
status而不是customer查詢訂單)?你需要一個 GSI——LSI 無法重新分割。 - 需要在同一個分割區內第二種排序順序——LSI 沿用資料表確切的分割區索引鍵、只換上一個不同的排序索引鍵——並且事先就決定好,還要讀取?那 LSI 就合適。
這個選擇歸結為一個問題——你要改的是哪個索引鍵:
不同的分割區索引鍵逼你用 GSI;同一個分割區上的不同排序索引鍵是唯一適合 LSI 的情況。
實務上大多數團隊幾乎清一色伸手拿 GSI:它們可以日後再加、獨立擴展,而且不受每個分割區 10 GB 上限的限制。把單一 GSI 的索引鍵過載來服務多種模式——見單表設計。
如果你正在加一個 GSI 來幹掉一個 Scan,記得它有自己的讀/寫容量。用定價計算器估算那筆額外成本,並試用 DynoTable,在你決定採用一個索引之前先檢視它投影的屬性。