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

クエリ パフォーマンスの分析

項目一覧

  • クエリのパフォーマンス評価

クエリの説明プランの結果は、MongoDB のバージョンによって変更される可能性があります。

MongoDB Compass には、クエリのパフォーマンスに関する統計を表示する [説明計画] タブが用意されています。これらの統計は、クエリでインデックスが使用されているかどうか、またどのように使用されているかを測定するために役立ちます。

以下のドキュメントを持つ inventory コレクションを考えてみましょう。

{ "_id" : 1, "item" : "f1", type: "food", quantity: 500 }
{ "_id" : 2, "item" : "f2", type: "food", quantity: 100 }
{ "_id" : 3, "item" : "p1", type: "paper", quantity: 200 }
{ "_id" : 4, "item" : "p2", type: "paper", quantity: 150 }
{ "_id" : 5, "item" : "f3", type: "food", quantity: 300 }
{ "_id" : 6, "item" : "t1", type: "toys", quantity: 500 }
{ "_id" : 7, "item" : "a1", type: "apparel", quantity: 250 }
{ "_id" : 8, "item" : "a2", type: "apparel", quantity: 400 }
{ "_id" : 9, "item" : "t2", type: "toys", quantity: 50 }
{ "_id" : 10, "item" : "f4", type: "food", quantity: 75 }

ドキュメントは MongoDB Compass に以下のように表示されます。

Compass Inventory コレクションに関するドキュメント

次のクエリは、quantity フィールドの値が 100 から 200 までの間のドキュメントを取得します。

db.inventory.find( { quantity: { $gte: 100, $lte: 200 } } )

このクエリでは次のドキュメントが返されます。

{ "_id" : 2, "item" : "f2", "type" : "food", "quantity" : 100 }
{ "_id" : 3, "item" : "p1", "type" : "paper", "quantity" : 200 }
{ "_id" : 4, "item" : "p2", "type" : "paper", "quantity" : 150 }

選択したクエリ プランを表示するには、 cursor.explain("executionStats") カーソル メソッドを find コマンドの後に続けて記述します。

db.inventory.find(
{ quantity: { $gte: 100, $lte: 200 } }
).explain("executionStats")

explain() は、次の結果を返します。

{
queryPlanner: {
...
winningPlan: {
queryPlan: {
stage: 'COLLSCAN',
...
}
}
},
executionStats: {
executionSuccess: true,
nReturned: 3,
executionTimeMillis: 0,
totalKeysExamined: 0,
totalDocsExamined: 10,
executionStages: {
stage: 'COLLSCAN',
...
},
...
},
...
}
  • queryPlanner.winningPlan.queryPlan.stage はコレクションスキャンを示す COLLSCAN を表示します。

    コレクションスキャンは、 mongod が結果を特定するためにコレクション全体をドキュメントごとにスキャンする必要があったことを示しています。これは通常、コストのかかる操作であり、クエリが遅くなる可能性があります。

  • executionStats.nReturned3 を表示し、選出されたクエリプランが 3 つのドキュメントを返すことを示します。

  • executionStats.totalKeysExamined は、このクエリがインデックスを使用していないことを示す0 を表示します。

  • executionStats.totalDocsExamined10 を表示し、3 つの一致するドキュメントを検索するために MongoDB が 10 個のドキュメント(つまり、コレクション内のすべてのドキュメント)をスキャンしなければならなかったことを示します。

次のクエリは、quantity フィールドの値が 100 から 200 までの間のドキュメントを取得します。

次のフィルターを Compass のクエリバーにコピーし、[Find] ボタンをクリックします。

{ quantity: { $gte: 100, $lte: 200 } }

このクエリでは次のドキュメントが返されます。

選択したクエリプランを表示する方法

  1. test.inventoryコレクションのExplain Planタブをクリックします。

  2. [Explain] をクリックします。

MongoDB Compass はクエリプランを次のように表示します。

Compass インデックスなしクエリプラン

注意

このチュートリアルでは、小さなデータセットを使用しているため、インデックスを使用していなくても Actual Query Execution Time0 秒と表示されます。

大規模なデータセットでは、インデックス付きのクエリとインデックスなしのクエリの実行時間の差がはるかに大きくなります。

  • Query Performance Summary には、クエリの実行統計が表示されます。

    • Documents Returned3 を表示し、選出されたクエリプランが 3 つのドキュメントを返すことを示します。

    • Index Keys Examined は、このクエリがインデックスを使用していないことを示す 0 を表示します。

    • Documents Examined10 を表示し、3 つの一致するドキュメントを検索するために MongoDB が 10 個のドキュメント(つまり、コレクション内のすべてのドキュメント)をスキャンしなければならなかったことを示します。

  • MongoDB Compass は [Query Performance Summary] の下に、COLLSCAN クエリ ステージを表示し、このクエリにコレクション スキャンが使用されたことを示します。

    コレクションスキャンは、 mongod が結果を特定するためにコレクション全体をドキュメントごとにスキャンする必要があったことを示しています。これは通常、コストのかかる操作であり、クエリが遅くなる可能性があります。

クエリ バーの下にある [Raw JSON] をクリックすることで、説明の詳細を未加工の JSON 形式で表示することもできます。

インデックス クエリプランを含まない Compass の未加工 JSON

一致するドキュメントの数と検査されたドキュメントの数との差から、クエリの効率を向上させるためには、インデックスを使用すると効果があると考えられます。

quantity フィールドのクエリをサポートするには、quantity フィールドにインデックスを追加します。

db.inventory.createIndex( { quantity: 1 } )

クエリプランの統計を表示するには、explain() メソッドを使用します。

db.inventory.find(
{ quantity: { $gte: 100, $lte: 200 } }
).explain("executionStats")

explain() メソッドは次の結果を返します。

{
queryPlanner: {
...
winningPlan: {
queryPlan: {
stage: 'FETCH',
inputStage: {
stage: 'IXSCAN',
keyPattern: {
quantity: 1
},
...
}
}
},
rejectedPlans: [ ]
},
executionStats: {
executionSuccess: true,
nReturned: 3,
executionTimeMillis: 0,
totalKeysExamined: 3,
totalDocsExamined: 3,
executionStages: {
...
},
...
},
...
}
  • queryPlanner.winningPlan.queryPlan.inputStage.stage はインデックスの使用を示すために IXSCAN を表示します。

  • executionStats.nReturned3 を表示し、選出されたクエリプランが 3 つのドキュメントを返すことを示します。

  • executionStats.totalKeysExamined3 を表示し、MongoDB が 3 つのインデックスエントリをスキャンしたことを示します。検査されたキーの数は、返されたドキュメントの数と一致します。つまり、mongod はインデックスキーを調べるだけで結果を返すことができました。mongod はすべてのドキュメントをスキャンする必要はなく、一致する 3 つのドキュメントのみをメモリに取り込む必要がありました。これにより、クエリが非常に効率的になります。

  • executionStats.totalDocsExamined3 を表示し、MongoDB が 3 つのドキュメントをスキャンしたことを示します。

  1. test.inventoryコレクションのIndexesタブをクリックします。

  2. [Create Index] をクリックします。

  3. Select a field nameドロップダウンからquantityを選択します。

  4. 型のドロップダウンから [1 (asc)] を選択します。

  5. [Create] をクリックします。

注意

[インデックス名] フィールドを空白のままにすると、MongoDB Compass はインデックスのデフォルト名を作成します。

これで [Indexes] タブに新しく作成したインデックスが表示されます。

Compass は新しいインデックスを表示します

inventory コレクションの [Explain Plan] タブに戻り、前の手順のクエリを再実行します。

{ quantity: { $gte: 100, $lte: 200 } }

MongoDB Compass はクエリプランを次のように表示します。

Compass はインデックス付きプランを説明します
  • Query Performance Summary には、クエリの実行統計が表示されます。

    • Documents Returned3 を表示し、選出されたクエリプランが 3 つのドキュメントを返すことを示します。

    • Index Keys Examined3 を表示し、MongoDB が 3 つのインデックスエントリをスキャンしたことを示します。調べられたキーの数は、返されたドキュメントの数と一致します。つまり、mongod はインデックス キーを調べるだけで結果を返すことができました。mongod はすべてのドキュメントをスキャンする必要はなく、一致する 3 つのドキュメントのみをメモリに取り込む必要がありました。これにより、クエリが非常に効率的になります。

    • Documents Examined3 を表示し、MongoDB が 3 つのドキュメントをスキャンしたことを示します。

    • MongoDB Compass は、[Query Performance Summary] の右側で、クエリが quantity インデックスを使用したことを示します。

  • Query Performance Summaryの下に、MongoDB Compass はクエリ ステージFETCHIXSCANを表示します。 IXSCANは、 mongodFETCHステージを実行してドキュメントを取得する前に、クエリを満たすためにインデックスを使用したことを示します。

クエリ バーの下にある [Raw JSON] をクリックすることで、説明の詳細を未加工の JSON 形式で表示することもできます。

インデックスを含む Compass クエリプランの未加工の JSON

インデックスがない場合、クエリは 10 個のドキュメントのコレクション全体をスキャンして、一致する 3 個のドキュメントを返します。クエリでは各ドキュメント全体をスキャンする必要があり、場合によってはドキュメントをメモリに取り込む必要もあります。その結果、クエリ操作にコストと時間がかかる可能性があります。

インデックスを使用して実行すると、クエリは 3 つのインデックスエントリと 3 つのドキュメントをスキャンして 3 つの一致するドキュメントを返すため、非常に効率的なクエリになりました。

Tip

以下も参照してください。

戻る

CRUD の概念