Docs Menu
Docs Home
/
MongoDBマニュアル
/

インデックスの管理

項目一覧

  • 既存のインデックスを表示
  • インデックスを削除する
  • インデックスを変更する
  • シャード間で一貫性のないインデックスを見つける

このページでは、既存のインデックスを管理する方法を説明します。インデックスの作成手順については、特定のインデックス型のページを参照してください。

次のセクションでは、コレクションまたはデータベース全体の既存のインデックスを表示する方法について説明します。

MongoDB Compass のコレクションにあるすべてのインデックスのリストを表示するには、左側のペインで対象のコレクションをクリックし、 Indexesタブを選択します。

Compass でコレクションのインデックスを表示する

このタブに表示される情報の詳細については、 Compass のドキュメントを参照してください。

コレクションのすべてのインデックスのリストを返すには、 db.collection.getIndexes()メソッドまたはドライバーの同様のメソッド を使用します。

例えば、 peopleコレクションのすべてのインデックスを表示するには、次のコマンドを実行します。

db.people.getIndexes()

データベース内のすべてのコレクション インデックスを一覧表示するには、 mongoshで次の操作を使用します。

db.getCollectionNames().forEach(function(collection) {
indexes = db[collection].getIndexes();
print("Indexes for " + collection + ":");
printjson(indexes);
});

バージョン3.0以降、 MongoDB では、以前はデータベース内のすべてのインデックスを一覧表示するために使用されていたsystem.indexesコレクションへの直接アクセスが廃止されます。

特定のタイプのすべてのインデックス(例: ハッシュされた 、テキスト)を含むすべてのデータベース内のすべてのコレクションに対して、 mongoshで次の操作を使用できます。

// The following finds all hashed indexes
db.adminCommand("listDatabases").databases.forEach(function(d){
let mdb = db.getSiblingDB(d.name);
mdb.getCollectionInfos({ type: "collection" }).forEach(function(c){
let currentCollection = mdb.getCollection(c.name);
currentCollection.getIndexes().forEach(function(idx){
let idxValues = Object.values(Object.assign({}, idx.key));
if (idxValues.includes("hashed")) {
print("Hashed index: " + idx.name + " on " + d.name + "." + c.name);
printjson(idx);
};
});
});
});

Tip

インデックスを削除する前に非表示にする

本番環境で頻繁に使用されているインデックスを削除すると、アプリケーションのパフォーマンスが低下する可能性があります。インデックスを削除する前に、インデックスを非表示にすることで、削除の潜在的な影響を評価できます。

非表示にされたインデックスはクエリのサポートに使用されることはありません。インデックスを非表示にしてパフォーマンスに大きな悪影響が見られる場合は、クエリがそのインデックスの使用を再開できるように、インデックスを保持して再表示することを検討してください。

MongoDB Shell でインデックスを削除するときは、次のいずれかを実行できます。

  • 特定のインデックスを削除します。

  • コレクションからすべてのインデックスを削除します。

インデックスを削除するには、 db.collection.dropIndex()メソッドを使用します。

たとえば、次の操作は、 accountsコレクションのtax-idフィールドの昇順インデックスを削除します。

db.accounts.dropIndex( { "tax-id": 1 } )

この操作は、操作のステータスを含むドキュメントを返します。

{ "nIndexesWas" : 3, "ok" : 1 }

ここで、 nIndexesWasの値は、このインデックスを削除するのインデックスの数を反映しています。

テキストインデックスの場合は、インデックス名をdb.collection.dropIndex()メソッドに渡します。 詳細については、「 インデックス名を使用してtextインデックスを削除する 」を参照してください。

注意

db.collection.dropIndexes() は、インデックス名の配列を受け入れることができます。

db.collection.dropIndexes()は進行中のインデックスビルドを停止できます。 詳細については、「 進行中のインデックスビルドの中止 」を参照してください。

また、 を使用して、 _iddb.collection.dropIndexes() インデックス を除く すべての インデックスをコレクションから削除することもできます。

たとえば、次のコマンドは、 accountsコレクションからすべてのインデックスを削除します。

db.accounts.dropIndexes()

これらのshellヘルパーは、 dropIndexesデータベースコマンドを囲むラッパーを提供します。 クライアント ライブラリには、これらの操作用に別のインターフェースまたは追加のインターフェースがある場合があります。

MongoDB Compass でコレクションからインデックスを削除するには次の手順に従います。

  1. ターゲット インデックスを含むコレクションに移動します。

  2. [Indexes] タブをクリックします。

  3. ターゲット インデックスのDrop列で、ゴミ箱アイコンをクリックします。

Compass でのインデックスの削除

MongoDB Shell で既存のインデックスを変更するには、インデックスを削除して再作成する必要があります。このルールの例外はTTL インデックスです。これは、 collModコマンドとindexコレクション フラグを組み合わせて変更できます。

MongoDB Compass で既存のインデックスを変更するには、インデックスを削除して再作成する必要があります。

本番環境で頻繁に使用されているインデックスを削除すると、アプリケーションのパフォーマンスが低下する可能性があります。変更中もクエリでインデックスを使用するには、変更されたインデックスと同じフィールドを含む一時的な冗長インデックスを作成できます。

この例では、新しいインデックスを作成し、そのインデックスを一意になるように変更します。

1

次のコマンドを実行します。

db.siteAnalytics.createIndex( { "url": 1 } )

このコマンドは、インデックスの名前を返します。

url_1
2

次のコマンドを実行します。

db.siteAnalytics.createIndex( { "url": 1, "dummyField": 1 } )

このコマンドは、インデックスの名前を返します。

url_1_dummyField_1

この一時インデックスにより、パフォーマンスに影響を与えずに元の { "url": 1 } インデックスを安全に削除できます。

3

次のコマンドを実行します。

db.siteAnalytics.dropIndex( { "url": 1 } )

このコマンドは、次のものを返します。

{ nIndexesWas: 3, ok: 1 }
4

次のコマンドを実行します。

db.siteAnalytics.createIndex( { "url": 1 }, { "unique": true } )

このコマンドは、インデックスの名前を返します。

url_1

url_1 インデックスが再作成され、パフォーマンスに影響を与えずに一時インデックスを削除できます。urlフィールドのクエリでは、新しい一意なインデックスを使用できます。

5

次のコマンドを実行します。

db.siteAnalytics.dropIndex( { "url": 1, "dummyField": 1 } )

このコマンドは、次のものを返します。

{ nIndexesWas: 3, ok: 1 }
6

siteAnalyticsコレクションのインデックスを表示するには、次のコマンドを実行します。

db.siteAnalytics.getIndexes()

このコマンドは次のインデックスを返します。これは、url_1 インデックスが一意になったことを示しています。

[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{ v: 2, key: { url: 1 }, name: 'url_1', unique: true }
]

コレクションのチャンクを含む各シャードにまったく同じインデックス(インデックスオプションを含む)がない場合、シャーディングされたコレクションのインデックスには一貫性がありません。通常の操作では一貫性のないインデックスは発生しないはずですが、次のような一貫性のないインデックスが発生する可能性があります。

  • ユーザーが unique キー制約を使用してインデックスを作成していて、1 つのシャードに重複ドキュメントを含むチャンクが含まれている場合。このような場合、インデックスの作成操作は、重複のないシャードでは成功するものの、重複のあるシャードでは成功しない可能性があります。

  • ユーザーが複数のシャードにわたってインデックスをローリング処理で作成している(複数のシャードにわたって手作業でインデックスを 1 つずつ構築している)時、関連付けられたシャードのインデックス作成に失敗した場合、または異なる仕様で誤ったインデックスを構築した場合。

コンフィギュレーションサーバーのプライマリにより、デフォルトでは、シャーディングされたコレクションのシャード間でのインデックスの不整合がチェックされます。コマンドserverStatusがコンフィギュレーションサーバーのプライマリで実行されると、フィールドshardedIndexConsistencyが返され、インデックスの不整合があるシャーディングされたコレクションの数を報告します。

shardedIndexConsistency でインデックスの不一致が報告された場合は、矛盾が見つかるまで、シャーディングされたコレクションに対して次のパイプラインを実行できます。

  1. 以下の集計パイプラインを定義する。

    const pipeline = [
    // Get indexes and the shards that they belong to.
    {$indexStats: {}},
    // Attach a list of all shards which reported indexes to each document from $indexStats.
    {$group: {_id: null, indexDoc: {$push: "$$ROOT"}, allShards: {$addToSet: "$shard"}}},
    // Unwind the generated array back into an array of index documents.
    {$unwind: "$indexDoc"},
    // Group by index name.
    {
    $group: {
    "_id": "$indexDoc.name",
    "shards": {$push: "$indexDoc.shard"},
    // Convert each index specification into an array of its properties
    // that can be compared using set operators.
    "specs": {$push: {$objectToArray: {$ifNull: ["$indexDoc.spec", {}]}}},
    "allShards": {$first: "$allShards"}
    }
    },
    // Compute which indexes are not present on all targeted shards and
    // which index specification properties aren't the same across all shards.
    {
    $project: {
    missingFromShards: {$setDifference: ["$allShards", "$shards"]},
    inconsistentProperties: {
    $setDifference: [
    {$reduce: {
    input: "$specs",
    initialValue: {$arrayElemAt: ["$specs", 0]},
    in: {$setUnion: ["$$value", "$$this"]}}},
    {$reduce: {
    input: "$specs",
    initialValue: {$arrayElemAt: ["$specs", 0]},
    in: {$setIntersection: ["$$value", "$$this"]}}}
    ]
    }
    }
    },
    // Only return output that indicates an index was inconsistent, i.e. either a shard was missing
    // an index or a property on at least one shard was not the same on all others.
    {
    $match: {
    $expr:
    {$or: [
    {$gt: [{$size: "$missingFromShards"}, 0]},
    {$gt: [{$size: "$inconsistentProperties"}, 0]},
    ]
    }
    }
    },
    // Output relevant fields.
    {$project: {_id: 0, indexName: "$$ROOT._id", inconsistentProperties: 1, missingFromShards: 1}}
    ];
  2. シャーディングされたコレクションの集計パイプラインを実行してテストします。たとえば、シャーディングされたコレクション test.reviews の関連するシャード全体でインデックスが一貫していないかどうかをテストするには次のようにします。

    db.getSiblingDB("test").reviews.aggregate(pipeline)

    コレクションに一貫性のないインデックスがある場合、そのコレクションの集計は、一貫性のないインデックスに関する詳細を返します。

    { "missingFromShards" : [ "shardB" ], "inconsistentProperties" : [ ], "indexName" : "page_1_score_1" }
    { "missingFromShards" : [ ], "inconsistentProperties" : [ { "k" : "expireAfterSeconds", "v" : 60 }, { "k" : "expireAfterSeconds", "v" : 600 } ], "indexName" : "reviewDt_1" }

    返されたドキュメントは、シャーディングされたコレクションtest.reviewsに 2つの不整合があることを示しています。

    1. page_1_score_1 という名前のインデックスが shardBのコレクションにありません。

    2. reviewDt_1 という名前のインデックスには、コレクションのシャード間で一貫性のないプロパティがあります。特に expireAfterSeconds プロパティが異なります。

特定のシャードのコレクションからインデックスが欠落しているという不整合を解決するには、

次のいずれかを実行できます。

  • 影響を受けたシャードでコレクションのローリングインデックス構築を実行します。

    -あるいは-

  • インデックス構築db.collection.createIndex()をインスタンスから mongos発行します。この操作では、インデックスがないシャードにのみコレクションのインデックスが構築されます。

シャード間でインデックス プロパティが異なる箇所を解決するには、

影響を受けるシャード上のコレクションから誤ったインデックスを削除し、インデックスを再構築します。インデックスを再構築するには、次のいずれかを実行します。

  • 影響を受けたシャードでコレクションのローリングインデックス構築を実行します。

    -あるいは-

  • インデックス構築db.collection.createIndex()をインスタンスから mongos発行します。この操作では、インデックスがないシャードにのみコレクションのインデックスが構築されます。

あるいは、expireAfterSeconds プロパティに不整合がある場合は、インデックスを削除して再構築する代わりに collMod コマンドを実行して秒数をアップデートすることもできます。

戻る

交差