4
3

More than 1 year has passed since last update.

MongoDBの実行計画について勉強してみた

Last updated at Posted at 2023-03-31

はじめに

  • 業務でMongoDBを触る機会が増えてきて、実行計画の見方を学びたいと思い記事にしました。
  • MongoDBのバージョンは5.0.15です。

実行計画とは

  • dbのクエリをどう処理するかについての計画です。db内部でいくつかの計画を比較し1つを実行してくれます。新しく追加したインデックスが使用されているか確認できたりします。

確認方法

  • 実行したいクエリにexplain()をつけると確認できます。
  • 引数に"executionStats"を指定すると実行された計画の詳細を確認できます。

例えば

db.getCollection("user").find({"age": 20})

というクエリの実行計画を見るには

db.getCollection("user").explain().find({"age": 20})

というふうにします。
詳細に見るには

db.getCollection("user").explain("executionStats").find({"age": 20})

というふうにします。

  • 今回サンプルで
{
    "_id" : ObjectId("641fc8ef5fbb0c5ad9193af9"),
    "name" : "名前",
    "age" : NumberInt(20),
    "region" : "山梨県"
}

こういったドキュメントを500個持つコレクションを作成しました(name,age,regionはランダムです)。

  • 実際に実行計画を確認したいと思います。
db.getCollection("user").explain("executionStats").find({"age": 20})

以下のようになものが表示されます。

{
    "explainVersion" : "1",
    "queryPlanner" : {
        "namespace" : "sample.user",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "age" : {
                "$eq" : 20.0
            }
        },
        "maxIndexedOrSolutionsReached" : false,
        "maxIndexedAndSolutionsReached" : false,
        "maxScansToExplodeReached" : false,
        "winningPlan" : {
            "stage" : "COLLSCAN",
            "filter" : {
                "age" : {
                    "$eq" : 20.0
                }
            },
            "direction" : "forward"
        },
        "rejectedPlans" : [

        ]
    },
    "executionStats" : {
        "executionSuccess" : true, 
        "nReturned" : 12.0,
        "executionTimeMillis" : 1.0,
        "totalKeysExamined" : 0.0,
        "totalDocsExamined" : 500.0,
        "executionStages" : {
            "stage" : "COLLSCAN",
            "filter" : {
                "age" : {
                    "$eq" : 20.0
                }
            },
            "nReturned" : 12.0,
            "executionTimeMillisEstimate" : 0.0,
            "works" : 502.0,
            "advanced" : 12.0,
            "needTime" : 489.0,
            "needYield" : 0.0,
            "saveState" : 0.0,
            "restoreState" : 0.0,
            "isEOF" : 1.0,
            "direction" : "forward",
            "docsExamined" : 500.0
        }
    },
//省略
  • 実行計画は"queryPlanner"で確認できます。
  • "winningPlan"に実行された計画が表示されます。
  • "rejectPlan"では候補に上がって実行されなかった計画が表示されます。
  • "winingPlan.stage"ではコレクションをどのように検索したかが表示されます。
  • "stage"がCOLLSCANの場合コレクション内を全てスキャンしていて、IXSCANの場合インデックスを使用してスキャンしています。今回インデックスを追加していないのでCOLLSCANになっています。
  • 次に実行された計画の詳細を"executionStats"で確認します。
  • "executionSuccess"で成功したか、"nReturned"で返すドキュメント数、"executionTimeMillis"でかかった時間が確認できます。
  • "totalKeysExamined"で走査したインデックス数が確認できます。今回インデックスが使われていないので0です。
  • "totalDocsExamined"で走査したドキュメント数が確認できます。インデックスが使われていないので全件走査しています。

最後に

  • 今回実行計画に見方について理解が深まったので、今後インデックスを追加する時に活かしていきたいです。

参考

https://tech.kitchhike.com/entry/2018/05/31/163715
https://qiita.com/koshilife/items/79a8d59fa0973c16de57

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3