【DynamoDB】LSI と GSI の違いをわかりやすく整理してみた
はじめに
DynamoDB を使い始めると必ず出てくる疑問が「LSI(ローカルセカンダリインデックス)と GSI(グローバルセカンダリインデックス)の違いって何?」です。
どちらも検索を柔軟にするための仕組みですが、設計の自由度やデータの整合性に大きな差があります。今回はそれを整理してみます。
LSI(Local Secondary Index) とは?
LSI は テーブル作成時にしか定義できないインデックス です。
特徴としては、パーティションキー → テーブル本体と同じ、ソートキー → テーブルとは別の属性を設定可能 です。
使用用途は「同じアイテムグループを別の並び順で見たい」などの時です。
例:ユーザーごとの注文履歴テーブルがある場合
- 本体テーブル:user_id × created_at
- LSI:user_id × amount
これで「ユーザーごとの注文を金額順に並べる」といったクエリが可能になります。
ただし、LSIには、下記の制約があります。
- テーブル作成時しか作れない
- パーティションごとのデータサイズ上限は 10GB
GSI(Global Secondary Index) とは?
GSI は テーブル作成後でも追加できるインデックス です。
特徴としては、パーティションキー → 本体とは別の属性を使える、ソートキー → 設定してもいいし、省略してもOK です。
使用用途は 「まったく違う検索軸を追加したい」などの時です。
例:注文履歴を「商品ID」で検索したい場合
- 本体テーブル:user_id × created_at
- GSI:product_id × created_at
これで「ある商品を購入したユーザーを探す」といった検索が可能になります。
また、その他の特徴としては、作成後に追加可能、テーブルとは独立したスループットを持てる、データサイズ制限なし などがあります。
データ整合性の違い
インデックスを設計する上で見落としがちなのが「整合性」の違いです。
LSI の整合性
- 本体と 同期的に更新 される
- 読み取り時は 強い整合性 と 結果整合性 の両方が選べる
- 最新のデータを確実に扱いたいときに使える
GSI の整合性
- 本体と 非同期で更新 される
- 読み取りは 結果整合性のみ
- 本体の更新が数秒遅れて反映されることがある
LSIとGSIの違いのまとめ
LSIとGSIの違いを簡単にまとめると下記のようになります。
特徴 | LSI | GSI |
---|---|---|
作成タイミング | テーブル作成時のみ | 後から追加可能 |
パーティションキー | テーブルと同じ | テーブルと別でも可 |
ソートキー | 別属性を設定可能 | 任意で設定可能 |
サイズ制限 | パーティションごとに 10GB | 制限なし |
スループット | テーブルと共有 | 独立して設定可能 |
インデックス更新 | 同期(即時反映) | 非同期(遅延あり) |
読み取り整合性 | 強い整合性/結果整合性 | 結果整合性のみ |
また、使い分けのイメージとしては、下記の通りです。
LSI
→ 「ユーザーごとの履歴を正確に並べ替えたい」
(例:履歴を作成日時順と金額順で使い分ける)
GSI
→ 「新しい検索軸を追加したい」
(例:商品IDから購入ユーザーを探す、配送先住所から検索する など)
まとめ
LSI は「整合性重視」だが作成タイミングや制約が多いです。また、GSI は「柔軟性重視」だが最新データが遅れる可能性があります。
実務的には GSI の方が利用頻度は高い ですが、ユーザーごとの正確な並び替えが必須な場面では LSI が活躍します。
参考
Discussion