mongodbクエリ文効率分析

6618 ワード

準備作業

  • 最新版mongodbをインストールします.
  • 無料のグラフィッククライアントRobo 3 T
  • をインストール
  • データベースlocalの下にtestというcollection
  • を作成
  • インデックスdb.test.createIndex( { a: -1, b:-1 }, {name:"ab"})
  • を作成する.
  • いくつかのデータを準備
  • {_id:1, a:1, b:2}
    {_id:2, a:1, b:2}
    {_id:3, a:1, b:3}
    {_id:4, a:1, b:3}
    {_id:5, a:2, b:2}
    {_id:6, a:2, b:2}
    {_id:7, a:2, b:3}
    {_id:8, a:2, b:3}
    

    インデックス解析

    db.test.find({a:1}).explain();
    

    実行結果
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "local.test",
            "indexFilterSet" : false,
            "parsedQuery" : {
                "a" : {
                    "$eq" : 1.0
                }
            },
            "winningPlan" : {
                "stage" : "FETCH",
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "a" : -1.0,
                        "b" : -1.0
                    },
                    "indexName" : "ab",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "a" : [],
                        "b" : []
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "a" : [ 
                            "[1.0, 1.0]"
                        ],
                        "b" : [ 
                            "[MaxKey, MinKey]"
                        ]
                    }
                }
            },
            "rejectedPlans" : []
        },
        "serverInfo" : {},
        "ok" : 1.0
    }
    

    キーパラメータの説明
    フィールド
    説明
    queryPlanner.indexFilterSet index filterが有効になっているかどうか、mongodbはindex filterを使用してインデックスを選択します.
    queryPlanner.winningPlan
    オプティマイザが最終的に選択したplanqueryPlanner.winningPlan.inputStage
    入力パラメータとインデックスのクエリー
    queryPlanner.winningPlan.inputStage.stage
    フェーズCOLLSCAN:スキャンcollection IXSCANスキャンインデックスFETCHドキュメントを読み込む
    queryPlanner.winningPlan.inputStage.keyPattern
    索引の書式は、索引の作成時の書式と一致します.
    queryPlanner.winningPlan.inputStage.indexBounds
    クエリー条件の制約値
    queryPlanner.rejectedPlans
    拒否された候補plan

    プロセス分析の実行

    db.test.find({a:1}).explain("executionStats");
    
    {
        "queryPlanner" : {   },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 4,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 4,
            "totalDocsExamined" : 4,
            "executionStages" : {
                "stage" : "FETCH",
                "nReturned" : 4,
                "executionTimeMillisEstimate" : 0,
                "works" : 5,
                "advanced" : 4,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "docsExamined" : 4,
                "alreadyHasObj" : 0,
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "nReturned" : 4,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 5,
                    "advanced" : 4,
                    "needTime" : 0,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "keyPattern" : {
                        "a" : -1.0,
                        "b" : -1.0
                    },
                    "indexName" : "ab",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "a" : [],
                        "b" : []
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "a" : [ 
                            "[1.0, 1.0]"
                        ],
                        "b" : [ 
                            "[MaxKey, MinKey]"
                        ]
                    },
                    "keysExamined" : 4,
                    "seeks" : 1,
                    "dupsTested" : 0,
                    "dupsDropped" : 0,
                    "seenInvalidated" : 0
                }
            }
        },
        "serverInfo" : {},
        "ok" : 1.0
    }
    

    キーフィールドの説明
    フィールド
    説明
    executionStats.totalKeysExamined
    インデックスの遍歴回数
    executionStats.totalDocsExamined
    ドキュメントを巡回する回数
    executionTimeMillisEstimate
    実行時間の予測
    遍歴の回数が多ければ多いほど、遍歴は遅くなるに違いない.この例ではインデックスを使用し、条件を満たす4つのドキュメントがあり、すべての遍歴回数は4である.

    インデックスを使用しない

    db.test.find({b:2}).explain("executionStats");
    
    {
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 4,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 0,
            "totalDocsExamined" : 8,
        },
    }
    

    db.test.find({b:2})はインデックス{a:1, b:1}を使用できないため、インデックスを巡回せずにcollection全体を巡回します.

    インデックスデータのみを返す

    db.test.find({a:2}, {_id:0, a:1, b:1}).explain("executionStats");
    
    {
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 4,
            "executionTimeMillis" : 0,
     	"totalKeysExamined" : 4,
            "totalDocsExamined" : 0,
            }
        },
    }
    

    この例ではmongodbはa,bの2回のフィールドしか返さないが、この2つのフィールドはちょうどインデックスを作成するのでdocumentを読み取る必要がないので、ドキュメントを遍歴しない.

    まとめ


    mongodbのインデックスはmysqlのインデックスとよく似ています