クエリ パフォーマンスの分析
項目一覧
クエリの説明プランの結果は、MongoDB のバージョンによって変更される可能性があります。
cursor.explain("executionStats")
とdb.collection.explain("executionStats")
メソッドは、クエリのパフォーマンスに関する統計を提供します。 これらの統計は、クエリでインデックスが使用されているかどうか、またどのように使用されているかを測定するために役立ちます。 詳細については、 db.collection.explain()
を参照してください。
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 に以下のように表示されます。
インデックスなしのクエリ
次のクエリは、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.nReturned
は3
を表示し、選出されたクエリプランが 3 つのドキュメントを返すことを示します。executionStats.totalKeysExamined
は、このクエリがインデックスを使用していないことを示す0
を表示します。executionStats.totalDocsExamined
は10
を表示し、3 つの一致するドキュメントを検索するために MongoDB が 10 個のドキュメント(つまり、コレクション内のすべてのドキュメント)をスキャンしなければならなかったことを示します。
次のクエリは、quantity
フィールドの値が 100
から 200
までの間のドキュメントを取得します。
次のフィルターを Compass のクエリバーにコピーし、[Find] ボタンをクリックします。
{ quantity: { $gte: 100, $lte: 200 } }
このクエリでは次のドキュメントが返されます。
選択したクエリプランを表示する方法
test.inventory
コレクションのExplain Planタブをクリックします。[Explain] をクリックします。
MongoDB Compass はクエリプランを次のように表示します。
注意
このチュートリアルでは、小さなデータセットを使用しているため、インデックスを使用していなくても Actual Query Execution Time が 0
秒と表示されます。
大規模なデータセットでは、インデックス付きのクエリとインデックスなしのクエリの実行時間の差がはるかに大きくなります。
ビジュアル ツリー
Query Performance Summary には、クエリの実行統計が表示されます。
Documents Returned は
3
を表示し、選出されたクエリプランが 3 つのドキュメントを返すことを示します。Index Keys Examined は、このクエリがインデックスを使用していないことを示す
0
を表示します。Documents Examined は
10
を表示し、3 つの一致するドキュメントを検索するために MongoDB が 10 個のドキュメント(つまり、コレクション内のすべてのドキュメント)をスキャンしなければならなかったことを示します。
MongoDB Compass は [Query Performance Summary] の下に、
COLLSCAN
クエリ ステージを表示し、このクエリにコレクション スキャンが使用されたことを示します。コレクションスキャンは、
mongod
が結果を特定するためにコレクション全体をドキュメントごとにスキャンする必要があったことを示しています。これは通常、コストのかかる操作であり、クエリが遅くなる可能性があります。
Raw JSON
クエリ バーの下にある [Raw JSON] をクリックすることで、説明の詳細を未加工の 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.nReturned
は3
を表示し、選出されたクエリプランが 3 つのドキュメントを返すことを示します。executionStats.totalKeysExamined
は3
を表示し、MongoDB が 3 つのインデックスエントリをスキャンしたことを示します。検査されたキーの数は、返されたドキュメントの数と一致します。つまり、mongod
はインデックスキーを調べるだけで結果を返すことができました。mongod
はすべてのドキュメントをスキャンする必要はなく、一致する 3 つのドキュメントのみをメモリに取り込む必要がありました。これにより、クエリが非常に効率的になります。executionStats.totalDocsExamined
は3
を表示し、MongoDB が 3 つのドキュメントをスキャンしたことを示します。
test.inventory
コレクションのIndexesタブをクリックします。[Create Index] をクリックします。
Select a field nameドロップダウンから
quantity
を選択します。型のドロップダウンから [
1 (asc)
] を選択します。[Create] をクリックします。
注意
[インデックス名] フィールドを空白のままにすると、MongoDB Compass はインデックスのデフォルト名を作成します。
これで [Indexes] タブに新しく作成したインデックスが表示されます。
inventory
コレクションの [Explain Plan] タブに戻り、前の手順のクエリを再実行します。
{ quantity: { $gte: 100, $lte: 200 } }
MongoDB Compass はクエリプランを次のように表示します。
ビジュアル ツリー
Query Performance Summary には、クエリの実行統計が表示されます。
Documents Returned は
3
を表示し、選出されたクエリプランが 3 つのドキュメントを返すことを示します。Index Keys Examined は
3
を表示し、MongoDB が 3 つのインデックスエントリをスキャンしたことを示します。調べられたキーの数は、返されたドキュメントの数と一致します。つまり、mongod
はインデックス キーを調べるだけで結果を返すことができました。mongod
はすべてのドキュメントをスキャンする必要はなく、一致する 3 つのドキュメントのみをメモリに取り込む必要がありました。これにより、クエリが非常に効率的になります。Documents Examined は
3
を表示し、MongoDB が 3 つのドキュメントをスキャンしたことを示します。MongoDB Compass は、[Query Performance Summary] の右側で、クエリが
quantity
インデックスを使用したことを示します。
Query Performance Summaryの下に、MongoDB Compass はクエリ ステージ
FETCH
とIXSCAN
を表示します。IXSCAN
は、mongod
がFETCH
ステージを実行してドキュメントを取得する前に、クエリを満たすためにインデックスを使用したことを示します。
Raw JSON
クエリ バーの下にある [Raw JSON] をクリックすることで、説明の詳細を未加工の JSON 形式で表示することもできます。
インデックスがない場合、クエリは 10
個のドキュメントのコレクション全体をスキャンして、一致する 3
個のドキュメントを返します。クエリでは各ドキュメント全体をスキャンする必要があり、場合によってはドキュメントをメモリに取り込む必要もあります。その結果、クエリ操作にコストと時間がかかる可能性があります。
インデックスを使用して実行すると、クエリは 3
つのインデックスエントリと 3
つのドキュメントをスキャンして 3
つの一致するドキュメントを返すため、非常に効率的なクエリになりました。