次の方法で共有


Azure Cosmos DB for MongoDB 仮想コアのインデックス作成に関するベスト プラクティス

適用対象: MongoDB 仮想コア

クエリ可能なフィールドには常にインデックスが作成されている必要がある

述語と集計に基づく読み取り操作では、対応するフィルターのインデックスを参照します。 インデックスがない場合、データベース エンジンはドキュメント スキャンを実行して、一致するドキュメントを取得します。 スキャンには常にコストがかかり、コレクション内のデータ量が増えるにつれて着実に高くなっていきます。 クエリのパフォーマンスを最適化するためには、クエリ可能なすべてのフィールドに対して常にインデックスを作成しておく必要があります。

不要なインデックスを回避し、すべてのフィールドに既定でインデックスが作成されないようにする

インデックスは、クエリ可能なフィールドに対してのみ作成する必要があります。 ワイルドカード文字によるインデックス作成は、ドキュメント構造内のフィールドがクエリ フィルターの一部になる可能性があり、クエリ パターンが予測できない場合にのみ使用する必要があります。

ヒント

Azure Cosmos DB for MongoDB 仮想コアでは、既定で _id フィールドのインデックスのみが作成されます。 他のすべてのフィールドは、既定ではインデックスが作成されません。 インデックスを作成するフィールドは、クエリのパフォーマンスを最大化するために事前に計画しておく必要がありますが、一方で作成するフィールドが多すぎると書き込みへの影響が出るため最小限に抑えなければなりません。

新しいドキュメントが初めて挿入されたときや、既存のドキュメントが更新または削除されたときに、インデックス内の指定された各フィールドも更新されます。 インデックス作成ポリシーに多数のフィールド (またはドキュメント内のすべてのフィールド) が含まれていると、対応するインデックスの更新時にサーバーによって使用されるリソースが増えます。 大規模に実行する場合は、クエリ可能なフィールドにのみインデックスを作成し、クエリ述語で使用されていない残りのフィールドはすべてインデックスから除外したままにする必要があります。

効率的なデータ インジェストのためのインデックス作成戦略

Azure Cosmos DB for MongoDB 仮想コアへの大規模なワークロード移行では、効率的に実行するために、データ読み込みの後にインデックスを作成することをお勧めします。 これにより、書き込みのオーバーヘッドが大幅に削減され、リソースの消費量が最小限に抑えられます。また、データ インジェストのパフォーマンスが向上します。 一括インジェスト中にインデックスを維持すると、各書き込み操作で該当するすべてのインデックスを更新する必要があります。そのため、挿入の速度が低下する可能性があります。

履歴データに対して複数のインデックスが作成された場合に、各フィールドに対して非ブロッキング createIndex コマンドを発行する

すべてのクエリ パターンに対して必ずしも事前に計画を立てられるわけではなく、特にアプリケーションの要件が進化するにつれてこれが難しくなります。 アプリケーションのニーズが変化することで、大量の履歴データが含まれるクラスターのインデックスにフィールドを追加することが余儀なくされています。

このようなシナリオでは、サーバーからの応答を待たずに、各 createIndex コマンドを非同期的に発行する必要があります。

既定では、インデックスが履歴データに完全に作成された後にのみ、Azure Cosmos DB for MongoDB 仮想コアが createIndex 操作に応答します。 クラスターのサイズや取り込まれたデータの量によってはこの操作に時間がかかり、サーバーが createIndex コマンドに応答していないかのように見える場合があります。

Mongo シェルで createIndex コマンドが発行されている場合は、Ctrl + C キーを押してコマンドを中断し、応答の待機を停止して次の一連の操作を実行します。

createIndex コマンドの発行後に Ctrl + C キーを使用してこのコマンドを中断しても、サーバーでのインデックスの作成操作は終了しません。 シェルがサーバーからの応答の待機を停止するだけで、サーバーでは既存のドキュメントに対して非同期的にインデックスの作成が継続されます。

複数のフィールドに述語を持つクエリの複合インデックスを作成する

複合インデックスは、次のシナリオで使用する必要があります。

  • 複数のフィールドにフィルターが適用されるクエリ
  • 複数のフィールドにフィルターを適用し、1 つ以上のフィールドを昇順または降順で並べ替えるクエリ

'cosmicworks' データベースと 'employee' コレクション内の次のドキュメントについて検討します

{
    "firstName": "Steve",
    "lastName": "Smith",
    "companyName": "Microsoft",
    "division": "Azure",
    "subDivision": "Data & AI",
    "timeInOrgInYears": 7
}

次のクエリを検討して、姓が 'Smith' の従業員すべてを、その組織に5年以上所属している条件で見つけ出します。

db.employee.find({"lastName": "Smith", "timeInOrgInYears": {"$gt": 5}})

'lastName' と 'timeInOrgInYears' の両方の複合インデックスによって、次のクエリが最適化されます。

use cosmicworks;
db.employee.createIndex({"lastName" : 1, "timeInOrgInYears" : 1})

createIndex 操作の状態を追跡する

インデックスが追加され、履歴データにインデックスを作成する必要がある場合は、db.currentOp() を使用してインデックス作成操作の進行状況を追跡できます。

このサンプルを検討して、'cosmicworks' データベースのインデックス作成の進行状況を追跡します。

use cosmicworks;
db.currentOp()

createIndex 操作が進行中の場合、応答は次のようになります。

{
  "inprog": [
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451493:1719209762286363",
      "op_prefix": 30000451493,
      "currentOpTime": "2024-06-24T06:16:02.000Z",
      "secs_running": 0,
      "command": { "aggregate": "" },
      "op": "command",
      "waitingForLock": false
    },
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451876:1719209638351743",
      "op_prefix": 30000451876,
      "currentOpTime": "2024-06-24T06:13:58.000Z",
      "secs_running": 124,
      "command": { "createIndexes": "" },
      "op": "workerCommand",
      "waitingForLock": false,
      "progress": {},
      "msg": ""
    }
  ],
  "ok": 1
}

大きなインデックス キーを既定で有効にする

ドキュメントに文字数の多いキーが含まれていない場合や、ドキュメントに複数のレベルの入れ子が含まれていない場合でも、大きなインデックス キーを指定すると、これらのシナリオが確実にカバーされます。 これで、大きなインデックス キーがエンジンの既定の動作になりました。

'cosmicworks' データベース内の 'large_index_coll' コレクションで大きなインデックス キーを有効にするには、このサンプルを検討します。

use cosmicworks;
db.runCommand(
{
 "createIndexes": "large_index_coll",
 "indexes": [
    {
        "key": { "ikey": 1 },
        "name": "ikey_1",
        "enableLargeIndexKeys": true
    }
    ]
})

ブロッキング オプションを使用した新しい書き込み操作に対するインデックス作成の優先順位付け

データが読み込まれる前にインデックスを作成する必要があるシナリオでは、ブロック オプションを使用して、インデックスの作成が完了するまで受信書き込みをブロックする必要があります。

{ "blocking": true }の設定は、データ書き込みを開始する前に空のコレクションにインデックスが作成される移行ユーティリティで役立ちます。

'cosmicworks' データベースの 'employee' コレクションでインデックスを作成する際のブロック オプションの例を検討します。

use cosmicworks;
db.runCommand({
  createIndexes: "employee",
  indexes: [{"key":{"name":1}, "name":"name_1"}],
  blocking: true
})

テキストベースのデータの効率的な検索とクエリを可能にする、テキスト インデックス作成を確認してください。

次のステップ