🕌

【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 が活躍します。

参考

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-indexes-general.html

Discussion