クエリとソート
SQL の WHERE のように感じるから Scan にフィルターを足し、コンソールが
一致する 20 行を見せているあいだにテーブル内の全アイテムを読んで支払う。その
パターンは、本番請求でいちばんよくある DynamoDB のコスト驚きだ。
DynamoDB の読み取りはキー付きだ。Query は 1 つのアイテムコレクションを
ソートキー順に歩き、Scan はテーブル全体に触れる。フィルター式はキャパシティが
課金されたあとで行を捨てる。ページネーションは LastEvaluatedKey を運ばなければ
ならない。ソートは選んだインデックスのソートキー経由であり、アプリメモリ内の
任意の列ではない。
読み終えたらできること
- 機能ごとに
QueryとScanを選び、パーティション範囲でその選択を防衛できる。 - アイテムを落としたり重複させたりせず、大きな結果セットをページできる。
- 可能ならキー条件でフィルターをかけ、読み取り後フィルターがまだいくら掛かるか 知っている。
- ソート順をソートキーにエンコードする — 降順読み取り、可変キー、数値順のための ゼロパディング。
読む順番
- Query 対 Scan — 他の読み取りガイドが理解を 前提にする課金の判断。
- ページネーション —
LastEvaluatedKey、 ページループ、そしてLimitが「返された行数」ではない理由。 - フィルタリング戦略 — キー条件対 フィルター式。キーが許す限り選択性を左へ押し込む。
- なぜ Scan は遅くて高いのか — テーブル
成長対パーティション成長。ワンオフの
Scanが許容されるとき。 - 並列スキャン — バルクエクスポート向けの
セグメント化
Scan。スループットのトレードオフ。 - ソートキー戦略 — 順序がアプリ内ではなく ディスク上にあるようソートキーを設計する。
- クエリの降順 —
ScanIndexForwardと 最新優先の読み取り。 - 可変ソートキー — ソートキーの変更が delete+put になるときと、それが GSI でいくらかかるか。
- ゼロパディングソート — 固定幅の数値
ソートキーで
ORDER#00042がORDER#00043の前に並ぶようにする。
PK = TENANT#acme と SK begins_with ORDER# の Query はそのテナントの注文だけを
読む。千万アイテムのテーブル上で filter status = OPEN の Scan は、それでも
数百万回の読み取り分のキャパシティを切り上げる。us-east-1 のオンデマンド料金では、
1 回の 4 KB 読み取りユニットは約 $0.000000125 — 呼び出しあたりは些細だが、
テーブル規模では容赦ない。料金計算機 が
実際の読み取りレートとアイテムサイズを見積もる。
並列スキャンはバルクエクスポート用に Scan をワーカーへ分割する。読み取り
スループットとコストを比例して増やす — 一回限りの移行には有用で、大きなテーブル上の
cron としては危険。可変ソートキーはアイテムのソート位置を変えるときに
delete-and-put を強制し、そのキーをインデックスするどの GSI でも書き込みが倍になる。
ゼロパディングの ORDER#00042 対 ORDER#42 は、ソートキーが数値 ID を運ぶ文字列の
ときの辞書順を直す。
DynoTable で
無料の クエリビルダー は、8 つのエクスポート対象で
ページネーションループ付きの完全な Query または Scan リクエストを組み立てる。
アプリではビジュアルなフィルタービルダーがインデックスを選び、導出された
Query 対 Scan バッジを示し、実行前にスキャンフィルターにフラグを立てる。
DynoTable をダウンロードして、ライブテーブルに対してこれらの読み取りを
実行しよう。クエリコストのステータスバーは、プランが分かるとき Workbench と
PartiQL タブで実行前ヒント(~N items · ~R RCU)を出し、驚く請求がコミット前に
表面化する。