Azure Cosmos DBのglobal secondary indexes(GSIs)が一般提供になったことで、パーティションキーに合わない検索のために、アプリ側でデータ複製や同期処理を自作する必要が大きく減りました。結論から言うと、既存コンテナーとは別のパーティションキーを持つ読み取り専用コンテナーを作り、Azure Cosmos DB側で自動同期させることで、クロスパーティションクエリを効率化できる機能です。
特に、ユーザーIDではなくメールアドレスで検索したい、注文データを顧客IDだけでなく注文IDでも引きたい、AIアプリで会話履歴や検索用インデックスを分離したい、といったケースで効果があります。一方で、GSIは万能な「後付け高速化ボタン」ではありません。RU消費、整合性、パーティションキー設計、初期同期時の負荷、運用監視を理解したうえで導入する必要があります。
この記事では、2026年6月にAzure Updatesで一般提供として掲載されたAzure Cosmos DB global secondary indexesについて、何が変わったのか、どの環境に影響するのか、管理者・開発者が導入前に確認すべきポイントを実務目線で整理します。Microsoftの公式ブログでは、GSIは「異なるパーティションキーを持つ自動同期されたデータコピー」と説明されており、クロスパーティションクエリのRUとレイテンシを抑える用途が中心です。(Microsoft for Developers)
Azure Cosmos DB global secondary indexesとは
Azure Cosmos DB global secondary indexesは、Azure Cosmos DB for NoSQLで使える、読み取り最適化のための追加コンテナーです。GSIはソースコンテナーのデータを基に作成されますが、ソースとは異なるパーティションキー、インデックスポリシー、スループット、データモデルを持てます。Microsoft Learnでは、GSIはソースコンテナーと自動同期される読み取り専用コンテナーであり、それぞれが独自のパーティションキー、RU上限、データモデルを持つと説明されています。(Microsoft Learn)
従来、Azure Cosmos DBではパーティションキーに合ったクエリは高速かつ低コストに実行できます。一方、パーティションキーを含まない検索条件では、複数パーティションにまたがるクロスパーティションクエリになりやすく、データ量が増えるほどRU消費とレイテンシが増加します。
たとえば、ユーザー情報コンテナーのパーティションキーを/customerIdにしている場合、customerIdでの検索は効率的です。しかし、メールアドレスでユーザーを探す処理が増えると、/emailAddressを軸にした検索は非効率になりがちです。GSIを使えば、/emailAddressをパーティションキーにした別コンテナーを作り、その検索を単一パーティションに近い形で実行できます。
これまでの課題
Azure Cosmos DBの設計では、最初に決めたパーティションキーが非常に重要です。とはいえ、実際のサービスでは運用後に検索要件が変わります。
よくある例は次のとおりです。
| システム例 | 当初のパーティションキー | 後から増えた検索条件 | 起きやすい問題 |
|---|---|---|---|
| 会員管理 | /customerId | メールアドレス、電話番号 | ログイン・問い合わせ対応でクロスパーティションクエリが増える |
| EC注文管理 | /customerId | 注文ID、配送ステータス | フルフィルメントやCS業務の検索が遅くなる |
| チャット・AIアプリ | /userId | セッションID、会話ID、検索用属性 | 会話履歴やRAG検索のアクセスパターンが増える |
| 業務SaaS | /tenantId | 担当者、ステータス、期限 | 管理画面やレポートの検索負荷が高くなる |
これまでは、別のパーティションキーを持つコンテナーを自分で用意し、Change Feed Processorなどを使って同期処理を実装する方法が一般的でした。しかし、この方法では同期コード、再試行、障害時の復旧、監視、ホスティング用のコンピュートリソースを自前で管理する必要があります。
GSIの一般提供により、この「別コンテナーへの同期パイプライン」をAzure Cosmos DBの機能として扱いやすくなった点が大きな変更です。
今回の一般提供で何が変わるのか
今回のポイントは、Azure Cosmos DB global secondary indexesがプレビュー段階の検証機能ではなく、本番利用を前提に検討しやすい一般提供機能になったことです。Azure Updatesでは「Launched」「General Availability」として掲載されており、Azure Cosmos DBのクエリ性能を、アプリケーションコードの複雑化を抑えながら改善できる機能として紹介されています。(マイクロソフトアジュール)
アプリケーションコードの複雑化を抑えられる
GSIの大きな利点は、アプリケーション側がソースコンテナーだけに書き込み、GSI側への反映はAzure Cosmos DBが非同期で処理する点です。
従来の自作構成では、次のような処理が必要でした。
| 従来の自作セカンダリインデックス | GSI利用時 |
|---|---|
| Change Feed Processorを実装する | Azure Cosmos DBが同期ジョブを管理する |
| 同期先コンテナーへの書き込みコードを書く | アプリは原則ソースコンテナーに書くだけ |
| 再試行、失敗時の復旧、監視を作り込む | GSIの同期遅延やエラーをAzure側のメトリックで監視する |
| 同期処理用のホストや運用が必要 | 追加のアプリケーション基盤を減らせる |
| 設計ミスで二重書き込み不整合が起きやすい | GSIは読み取り専用で、同期はサービス側が管理する |
開発者にとっては、データアクセス層の責務を減らせるのが利点です。管理者にとっては、同期処理のためだけに用意していたAzure Functions、Container Apps、VM、Kubernetesジョブなどを見直すきっかけになります。
クロスパーティションクエリを減らせる
GSIは、ソースコンテナーとは異なるパーティションキーでデータを保持できます。そのため、これまでクロスパーティションクエリになっていた検索を、GSI側では効率的なクエリに変えられる可能性があります。
たとえば、ソースコンテナーが次の設計だったとします。
{
"id": "order-001",
"customerId": "customer-123",
"orderId": "order-001",
"status": "shipped",
"createdAt": "2026-06-03T10:00:00Z"
}
ソースコンテナーのパーティションキーが/customerIdなら、顧客ごとの注文検索は得意です。しかし、配送システムがorderIdで注文を検索する場合、customerIdが分からなければ非効率な検索になりやすくなります。
この場合、/orderIdをパーティションキーにしたGSIを作成すれば、配送システム向けの検索を効率化できます。
AI・検索ワークロードを分離しやすくなる
GSIは、AIアプリやエージェント型アプリでも有効です。Microsoftの公式ブログでは、AIやエージェントアプリではユーザーデータ、セッション状態、会話履歴などのクエリパターンが変化しやすく、GSIによりデータモデルを大きく作り替えずに新しいアクセスパターンを追加できると説明されています。(Microsoft for Developers)
また、GSIコンテナーは独自のスループットやインデックスポリシーを持てるため、ソースコンテナーのトランザクション処理と、ベクトル検索・全文検索・ハイブリッド検索のような読み取り負荷を分離しやすくなります。Microsoft Learnでも、GSIではベクトル検索、全文検索、ハイブリッド検索を含むAzure Cosmos DB for NoSQLのクエリ構文を利用できるとされています。(Microsoft Learn)
影響範囲:誰が確認すべきか
Azure Cosmos DB global secondary indexesの一般提供は、すべての利用者に即時の作業を強制する変更ではありません。ただし、次のいずれかに当てはまる環境では、導入効果を確認する価値があります。
| 対象者 | 確認すべき理由 |
|---|---|
| Azure管理者 | RU、バックアップ設定、監視、コスト影響を評価する必要がある |
| アプリ開発者 | 既存の検索処理やデータアクセス層を簡素化できる可能性がある |
| DB設計担当者 | パーティションキー設計の補完策として使えるか判断する必要がある |
| SRE・運用担当 | 同期遅延、429、HTTPエラー、RU消費の監視設計が必要になる |
| AIアプリ開発者 | 会話履歴、検索用データ、ベクトル・全文検索の分離に使える可能性がある |
特に確認したいのは、すでに「セカンダリインデックス用コンテナー」を自作している環境です。GSIで置き換えられる可能性があり、アプリケーションコードや運用基盤を削減できるかもしれません。
GSIを使うべきケース、使わないほうがよいケース
GSIは便利ですが、すべてのクエリに追加すればよいものではありません。導入判断では、「頻度」「コスト」「一貫性」「データモデル変更の可否」を見ます。
使うべきケース
GSIが向いているのは、次のような状況です。
| 判断基準 | 具体例 |
|---|---|
| パーティションキー以外で頻繁に検索する | customerIdではなくemailAddressでユーザーを検索する |
| クロスパーティションクエリのRUが高い | 管理画面の検索で毎回多くのRUを消費している |
| アクセスパターンが複数ある | 注文を顧客別、注文ID別、ステータス別に検索したい |
| 自作同期コードを減らしたい | Change Feed Processorで別コンテナーを手動同期している |
| 読み取り負荷を分離したい | AI検索、全文検索、レポート系クエリをトランザクション処理から分けたい |
実務では、まずAzure PortalやAzure MonitorでRU消費が大きいクエリを洗い出します。その中から、特定のプロパティで絞り込む頻度が高く、かつ現在のパーティションキーに合っていないものをGSI候補にします。
使わないほうがよいケース
一方、次のケースではGSIよりも別の対策を優先すべきです。
| 状況 | 理由 |
|---|---|
| 低頻度の管理用検索だけ | GSIのストレージ・RU・監視コストに見合わない可能性がある |
| 強い整合性が必要な直後読み取り | GSIは非同期同期であり、ソースと即時一致しない可能性がある |
| 元のパーティションキー設計が明らかに不適切 | GSIで補うより、データモデル全体の見直しが必要な場合がある |
| すべての属性で検索したい | GSIを増やしすぎるとコストと運用が複雑になる |
| パーティションキー候補にnullや偏りが多い | 論理パーティションの偏りやサイズ制限に近づく恐れがある |
GSIは「設計ミスをすべて隠す機能」ではありません。あくまで、重要な追加アクセスパターンに対して、読み取り効率を上げるための選択肢です。
管理者が確認すべき設定
Azure管理者やインフラ担当者は、GSIを作る前にアカウント設定、RU、監視、バックアップを確認する必要があります。
Continuous backupが有効か確認する
GSIを有効化するには、Azure Cosmos DBアカウントでContinuous backupを有効にしておく必要があります。Microsoft Learnの設定手順でも、GSIを有効化する前提としてContinuous backupsをオンにする必要があると明記されています。(Microsoft Learn)
既存アカウントでGSIを検討する場合は、まず次を確認します。
| 確認項目 | 見るポイント |
|---|---|
| バックアップモード | Continuous backupが有効か |
| 復旧要件 | 現在のRPO/RTO設計と矛盾しないか |
| コスト | バックアップ設定変更による費用影響を確認する |
| 環境差異 | 開発・検証・本番で設定が揃っているか |
本番環境でいきなり設定を変えるのではなく、検証環境で同じ構成を再現し、GSI作成と同期の挙動を確認してから展開するのが安全です。
GSIコンテナーはautoscale throughputが必要
GSIコンテナーはautoscale throughputを使う必要があります。Microsoft Learnの作成手順では、GSIコンテナーはautoscale throughputを使用する必要があると説明されています。(Microsoft Learn)
これは、初期作成時やソースコンテナーの更新が多いタイミングで同期負荷が増えるためです。スループットが不足すると、GSIへの反映が遅れたり、同期処理が追いつきにくくなったりします。
導入時は、次のように考えます。
| フェーズ | スループット設計の考え方 |
|---|---|
| 初期構築 | 既存データをGSIへ反映するため、一時的にRU需要が上がる可能性を見込む |
| 通常運用 | ソースの更新頻度とGSIの読み取り頻度を分けて見積もる |
| キャンペーン・繁忙期 | 書き込み急増時に同期遅延が広がらないよう監視する |
| コスト最適化 | 反映遅延とRU上限のバランスを見ながら調整する |
replace/deleteの追加RUを見込む
GSIを作ると、ソースコンテナー側の一部操作で追加RUが発生します。Microsoft Learnでは、1つ以上のGSIを持つソースコンテナーでは、replaceおよびdelete操作に対して、アイテムサイズに応じてベース書き込みRUの50〜100%の追加RUが発生し、create操作は影響を受けないと説明されています。(Microsoft Learn)
この点は、コスト見積もりで見落としやすいポイントです。
| 操作 | GSI導入時の注意 |
|---|---|
| create | 公式ドキュメント上、追加RUの対象ではない |
| replace | 追加RUを見込む必要がある |
| delete | 追加RUを見込む必要がある |
| read | GSI側の読み取りRUとして別途消費される |
| 初期同期 | ソース読み取りとGSI書き込みの両方を監視する |
更新・削除が多いワークロードでは、GSIによる読み取り改善よりも、書き込み側のRU増加が大きくなる可能性があります。導入前に、直近の操作比率を確認してください。
開発者が確認すべき設計ポイント
開発者は、GSIを「どのクエリに使うか」「どのプロパティを投影するか」「どのコンテナーを参照するか」を明確にしてから実装します。
GSI定義は作成後に変更できない
GSIのソースコンテナーと定義クエリは、作成後に変更できません。Microsoft Learnでは、ソースコンテナーとdefinition queryはGSI作成後に変更できないと説明されています。(Microsoft Learn)
これは非常に重要です。試しに作ったGSIを後から少し修正する、という運用はしにくいため、検証環境で定義を固める必要があります。
GSI定義前に、少なくとも次を決めます。
| 設計項目 | 確認すること |
|---|---|
| GSIの目的 | どのクエリを高速化するのか |
| パーティションキー | 検索条件に必ず含められるか、値の偏りがないか |
| 投影プロパティ | クエリ結果に必要な項目だけを含めるか |
| インデックスポリシー | 実行するクエリに合っているか |
| 読み取り側コード | ソースとGSIのどちらを参照するか明確か |
| 整合性 | 非同期反映でも業務上問題ないか |
定義クエリには制約がある
GSIの定義クエリでは、任意のクエリが使えるわけではありません。Microsoft Learnによると、SELECTでプロパティを投影できますが、プロパティエイリアスは使えず、WHERE、JOIN、DISTINCT、GROUP BY、ORDER BY、TOP、OFFSET LIMIT、EXISTSなどの句は含められません。また、システム関数やUDFもサポートされません。(Microsoft Learn)
たとえば、次のような考え方になります。
| やりたいこと | GSI定義での考え方 |
|---|---|
| 必要な項目だけ持たせたい | SELECT c.id, c.emailAddress, c.customerId FROM cのように投影する |
| 条件に合うデータだけ持たせたい | WHERE c.status = 'active'のような定義は使えない |
| ネストされた値を使いたい | 投影するとGSI側ではトップレベルにフラット化される |
| すべての項目を持たせたい | SELECT *は使えるが、ストレージとRU増加に注意する |
実務では、SELECT *を安易に使わず、検索と表示に必要な項目だけを投影するほうが、コストと運用の面で有利です。
GSIは読み取り専用として扱う
GSIコンテナーは読み取り専用です。アプリケーションからGSIへ直接書き込むのではなく、書き込みはソースコンテナーに対して行います。GSIへの反映はAzure Cosmos DBが非同期で処理します。
アプリケーション側では、次のように責務を分けると分かりやすくなります。
| 処理 | 参照先・書き込み先 |
|---|---|
| 新規作成 | ソースコンテナー |
| 更新 | ソースコンテナー |
| 削除 | ソースコンテナー |
| 主キー・元のパーティションキーでの検索 | ソースコンテナー |
| 追加アクセスパターンでの検索 | GSIコンテナー |
| 厳密な最新状態が必要な確認 | ソースコンテナーを優先 |
GSIのデータは非同期で反映されるため、更新直後にGSIを読むと、まだ古い状態が返る可能性があります。決済、在庫確定、権限判定など、直後の整合性が重要な処理では慎重に扱ってください。
移行時の考え方:自作インデックスからGSIへ置き換える手順
すでにChange Feed Processorなどで別コンテナーに同期している場合、GSIに移行できる可能性があります。ただし、いきなり既存処理を削除するのは危険です。段階的に切り替えます。
| 手順 | 作業内容 | 確認ポイント |
|---|---|---|
| 現状分析 | 既存のセカンダリコンテナーと同期コードを棚卸しする | どのクエリのために存在するか |
| 候補選定 | GSIで代替できるアクセスパターンを選ぶ | WHERE条件や加工処理がGSI定義に収まるか |
| 検証環境で作成 | 同じデータモデルでGSIを作る | 初期同期時間、RU、データ件数 |
| 読み取り比較 | 既存コンテナーとGSIの結果を比較する | 件数、欠損、遅延、レスポンス |
| 一部切り替え | 読み取り処理だけGSI参照に変更する | エラー率、レイテンシ、RU |
| 監視強化 | 同期遅延とHTTPエラーをアラート化する | 運用で検知できる状態か |
| 旧処理停止 | 問題がなければ自作同期処理を停止する | ロールバック手順を残す |
移行では、結果の完全一致だけでなく、遅延を許容できる業務かどうかを確認してください。GSIは非同期同期のため、リアルタイム性が必要な処理にはソースコンテナーの参照を残す設計が現実的です。
展開時に失敗しやすいポイント
GSI導入でよくある失敗は、パーティションキーとRUの見積もり不足です。以下のポイントを事前に確認すると、導入後のトラブルを減らせます。
nullが多いプロパティをパーティションキーにしない
GSIのパーティションキーには、ほぼすべてのアイテムに存在し、値が適度に分散するプロパティを選びます。Microsoft Learnでは、投影プロパティが存在しない場合はnullが使われ、存在しない値をパーティションキーに選ぶと20GBの論理パーティションサイズ制限に近づく可能性があると注意されています。(Microsoft Learn)
避けたい例は次のような設計です。
{
"id": "user-001",
"customerId": "customer-001",
"phoneNumber": null
}
phoneNumberが多くのアイテムでnullの場合、/phoneNumberをGSIのパーティションキーにすると、nullにデータが偏る可能性があります。検索したい項目であっても、値の存在率と分散を確認してから選ぶ必要があります。
GSIを増やしすぎない
GSIは複数作成できますが、アクセスパターンごとに無制限に増やすと、ストレージ、RU、監視対象が増えます。GSIは「頻繁に使う重要な検索」に絞るのが基本です。
判断に迷う場合は、次の条件を満たすものを優先します。
| 優先度が高いGSI候補 | 理由 |
|---|---|
| ユーザー操作に直結する検索 | レイテンシ改善が体感品質に影響する |
| 実行頻度が高い検索 | RU削減効果が大きい |
| 現在クロスパーティションで高コストな検索 | 改善余地が大きい |
| 自作同期処理が複雑な検索 | 運用削減効果がある |
| AI・検索系でトランザクション処理と分離したい検索 | ワークロード分離の効果がある |
月に数回しか実行しない管理用検索であれば、GSIではなく、バッチ処理、分析基盤、管理用エクスポートなどで対応したほうがよい場合もあります。
初期構築時の同期遅延を見落とさない
既存データが多いソースコンテナーにGSIを作ると、初期同期に時間がかかる可能性があります。GSIが作成された直後に本番トラフィックを流すのではなく、同期状態を確認してから読み取り先を切り替えるべきです。
Microsoft Learnでは、GSIの同期状況を確認するために「Global Secondary Index Propagation Latency in Seconds」メトリックを利用できると説明されています。これは、ソースとGSIの間の反映遅延を確認するための重要なメトリックです。(Microsoft Learn)
展開時は、次のメトリックを確認します。
| 監視項目 | 見るべき内容 |
|---|---|
| Global Secondary Index Propagation Latency in Seconds | ソースからGSIへの反映遅延 |
| Normalized RU Consumption | ソース・GSIのRU逼迫 |
| HTTP status code 400以上 | GSI書き込み時のエラー |
| 429 Too Many Requests | スループット不足の兆候 |
| クエリレイテンシ | GSI導入後に期待どおり改善しているか |
特に、GSIの伝播は非同期です。同期遅延が業務影響につながる場合は、アラートを設定しておく必要があります。
導入前チェックリスト
本番導入前には、次の項目を確認してください。
| チェック項目 | 確認内容 |
|---|---|
| 対象API | Azure Cosmos DB for NoSQLであること |
| バックアップ | Continuous backupが有効であること |
| GSIの目的 | どのクエリを改善するのか明確であること |
| パーティションキー | 値が存在し、偏りが少ないこと |
| 定義クエリ | 制約内で表現できること |
| 投影プロパティ | 必要最小限に絞っていること |
| スループット | GSIにautoscale throughputを設定すること |
| コスト | replace/deleteの追加RUを見込んでいること |
| 整合性 | 非同期反映を許容できること |
| 監視 | 伝播遅延、RU、HTTPエラーのアラートを用意すること |
| 移行計画 | 既存処理から段階的に切り替えられること |
| ロールバック | 読み取り先をソースや旧コンテナーに戻せること |
このチェックリストで不明点が多い場合は、すぐにGSIを本番作成するのではなく、まず代表的なクエリを1つ選び、検証環境でRUとレイテンシを比較するのが現実的です。
実務でのおすすめ導入パターン
最初のGSIは、効果が測りやすく、業務リスクが低い検索から始めるのがおすすめです。
たとえば、次のようなパターンです。
| 導入パターン | 内容 |
|---|---|
| ログイン補助検索 | customerId中心の設計に対し、emailAddress検索用GSIを作る |
| 注文照会 | 顧客別注文とは別に、orderId検索用GSIを作る |
| 管理画面の高速化 | ステータスや担当者で絞る頻出検索をGSIに逃がす |
| AI検索分離 | 会話履歴や検索対象データをGSIに投影し、ベクトル・全文検索用に最適化する |
| 旧同期処理の削減 | 自作のChange Feed同期コンテナーをGSIで置き換える |
最初から多くのGSIを作るのではなく、1つの高頻度クエリで効果を確認します。RU、レイテンシ、同期遅延、アプリ修正量、運用負荷を比較し、効果が見えたら次の候補へ広げます。
Azure Cosmos DB global secondary indexesは「後から増えた検索要件」への有力な選択肢
Azure Cosmos DB global secondary indexesの一般提供により、Azure Cosmos DB for NoSQLでは、後から増えた検索要件に対して、より現実的な対応が取りやすくなりました。特に、パーティションキーに合わない検索、AI・検索ワークロードの分離、自作同期処理の削減に効果があります。
一方で、GSIは非同期同期であり、RUやストレージコストも発生します。replace/deleteの追加RU、autoscale throughput、Continuous backup、同期遅延の監視を確認せずに導入すると、期待したほどの効果が出ない可能性があります。
次に取るべき行動は、既存のAzure Cosmos DBで「RU消費が大きいクロスパーティションクエリ」を1つ洗い出すことです。そのクエリが特定のプロパティで頻繁に検索しているものであれば、GSIの候補になります。検証環境で同じデータ量に近い条件を作り、ソースコンテナーとGSIでRU、レイテンシ、同期遅延を比較してから、本番展開を判断してください。

コメント