中階閱讀時間 3 分鐘

DynamoDB 指數預測

建立二級索引時,DynamoDB 不會自動複製整個項目進入其中。你選擇複製的內容——也就是索引的投影。選得太少,查詢就得再讀一次才能拿到其餘屬性;全選則每次更新都要多付儲存與寫入成本。這是你在建立索引時定下、之後一路承受的權衡。

(不要將其與 投影表達式 混淆,它會修剪屬性單讀_返回_。本頁介紹的是 索引實際儲存的內容 — 請參閱 projection expressions 為另一個。)

什麼是 DynamoDB 索引投影?

投影是 DynamoDB 從基底表複製到二級索引的屬性集。你可以選擇以下三種類型之一:DynamoDB(僅鍵)、INCLUDE(鍵加上指定的屬性清單)或 ALL(整個項目)。更多的投影意味著更少的基表獲取,但更高的存儲和寫入成本。

  • 投影是複製到二級索引的屬性集。
  • GSI — 僅表和索引鍵。最小的,最便宜的。
  • LSI — 鍵加上你選擇的額外屬性的命名清單。
  • ALL — 物品的每個屬性。最大;查詢永遠不需要基表。
  • 未投影的屬性根本無法從 GSI 中獲得 - 你的應用程式必須發出自己的基表讀取。(只有 LSI 取得非投影屬性你,需要額外閱讀費用。)
  • 更多投影=更多存儲+更多寫入成本,因為每次基表寫入傳播到索引。

問題:索引讓你讀了兩遍

假設你使用 GSI 運行一個支援台,該支援台可讓你按優先順序列出 開放 票證。你計劃 GSI 以保持精簡。查詢返回得很快——但它只給你工單 ID,你的隊列畫面需要每張工單的主題、受讓人和年齡。

所以現在你的程式碼對基底表進行第二輪讀取以水合每個結果。你設計的「一個查詢」其實是一個查詢加N個獲取,而你試圖節省的延遲和成本馬上又回來了。投影太薄對於訪問模式。

每種投影類型複製的內容

基本項目:關鍵字+主題+受讓人+年齡+正文KEYS_ONLY:僅鍵包括:鍵 + 主題、受讓人、年齡全部:每個屬性
  • KEYS_ONLY 僅儲存基底表鍵 索引鍵。當查詢只需要知道_哪些_項目匹配,你就可以在其他地方取得詳細資訊 - 或者一點也不。
  • INCLUDE 儲存金鑰以及你命名的屬性的固定清單。甜蜜的 Spot:準確投影你的查詢需要呈現的字段,僅此而已。
  • ALL 複製整個專案。查詢完全由索引自助提供,位於複製整個專案的儲存和寫入吞吐量的成本。

對於支援台隊列,INCLUDEsubjectassigneeage 是正確的呼叫 - 佇列僅從索引渲染,沒有第二次獲取,也沒有將票據的大 body 複製到索引中。

你交易的成本

你投射的每個屬性都是 ZZ保留0ZZ 並且每當基本項發生變更時就會在索引中重寫。這麼慷慨的ALL 對頻繁更新的表進行投影會使儲存和寫入容量倍增。規則是:預測查詢_讀取_的內容,而不是「一切,以防萬一」。

一個值得了解的微妙之處:使用稀疏索引,投影仍然只包含帶有索引鍵的項 — 因此 INCLUDE/ALL 位於 sparse index 保持較小,因為索引本身是小。權衡你的投影的儲存和寫入乘數 DynamoDB pricing calculator,並組裝索引查詢本身 DynamoDB expression builder

在 DynoTable 中查看投影

DynoTable 列出表格的每個二級索引並讓你直接查詢一。針對基底表和 GSI 運行相同的存取模式並進行比較結果 - 索引結果中缺少的屬性正是它所包含的屬性不投影,因此無需重新讀取表格即可看到投影效果定義。

在 DynoTable 的索引選擇器中選擇查詢執行的 DynamoDB 索引。
在 DynoTable 的索引選擇器中選擇查詢執行的 DynamoDB 索引。

陷阱與後續步驟

  • GSI 上的非投影屬性表示基底表取得 — 設計圍繞查詢呈現的內容進行投影。
  • GSI 很少是免費的 — 它會重複儲存和寫入成本;預設為 GSI 除非索引確實需要每個欄位。
  • 投影大部分是固定的。 你以後無法自由編輯 GSI 的投影無需重新建立索引-預先謹慎選擇。
  • 相關: GSI vs LSIsparse indexes形狀投影多少錢一個實際上商店。

想要在重新設計每個索引之前了解它們實際返回的內容嗎? Download DynoTable 並直接查詢你的表。

水合消耗:KEYS_ONLY + N 次

返回支援台佇列範例:50 個開放票證顯示為主題、受讓人和年齡。

投影索引查詢後續閱讀EC RCU 草圖(2 KB 基本項目)
KEYS_ONLY已退回 50 把鑰匙50×GetItem~50 索引 RCU + ~50 基礎 RCU
INCLUDE 主題、受讓人、年齡50 行獨立僅約 50 個指數 RCU
ALL50 份完整版~50 指數 RCU;更高的存儲+寫入放大器

確切的數字取決於預計的屬性大小 - 將範例票證貼到 item-size calculator 並相乘通過隊列深度。僅列出 UI 欄位的 INCLUDE 通常優於 ALL,當 body 屬性很大,很少在清單視圖中顯示。

LSI 投影獲取行為

只有 LSI 可以選擇從基底表中取得非投影屬性在查詢期間(有額外的讀取成本)。 GSI 從來不這樣做 — 缺失屬性要求你的應用程式在基底表上呼叫 GSI。那差異將許多 GSI 設計推向稍寬的 INCLUDE 投影在前面。

稍後更改預測

GSI 投影在創建時是固定的。將 GSI 拓寬至 INCLUDE 需要建立新索引、回填、截斷流量、刪除舊索引 - 在啟動前規劃欄位。 LSI 也有同樣的限制。

當評估新的存取模式時,查詢 DynoTable 中的候選索引並列出出現的屬性 - 間隙以 1:1 的比例對應到缺少的投影條目。

與稀疏索引配對

僅索引 GSI 票證的稀疏 GSI 儲存預測僅開放行。即使基表在該索引上的 INCLUDE 仍然很便宜持有數百萬張已關閉的票據——指數從未複製它們。

sparse index patterns 結合使用時過濾後的子集相對於表來說很小。

首先建構存取模式

在你動 CloudFormation 之前,先用查詢構建器把這次 GSI 查詢做成原型——鍵條件、投影運算式和過濾條件。在設計討論裡換投影類型時,問一句 UI 到底渲染了哪幾列就行;其餘一切都留在基表上。

已更新