Exemple #1
0
    // static
    void Explain::generatePlannerInfo(CanonicalQuery* query,
                                      PlanStageStats* winnerStats,
                                      const vector<PlanStageStats*>& rejectedStats,
                                      BSONObjBuilder* out) {
        BSONObjBuilder plannerBob(out->subobjStart("queryPlanner"));;

        plannerBob.append("plannerVersion", QueryPlanner::kPlannerVersion);

        // In general we should have a canonical query, but sometimes we may avoid
        // creating a canonical query as an optimization (specifically, the update system
        // does not canonicalize for idhack updates). In these cases, 'query' is NULL.
        if (NULL != query) {
            BSONObjBuilder parsedQueryBob(plannerBob.subobjStart("parsedQuery"));
            query->root()->toBSON(&parsedQueryBob);
            parsedQueryBob.doneFast();
        }

        BSONObjBuilder winningPlanBob(plannerBob.subobjStart("winningPlan"));
        explainStatsTree(*winnerStats, Explain::QUERY_PLANNER, &winningPlanBob);
        winningPlanBob.doneFast();

        // Genenerate array of rejected plans.
        BSONArrayBuilder allPlansBob(plannerBob.subarrayStart("rejectedPlans"));
        for (size_t i = 0; i < rejectedStats.size(); i++) {
            BSONObjBuilder childBob(allPlansBob.subobjStart());
            explainStatsTree(*rejectedStats[i], Explain::QUERY_PLANNER, &childBob);
        }
        allPlansBob.doneFast();

        plannerBob.doneFast();
    }
Exemple #2
0
    // static
    void Explain::generatePlannerInfo(CanonicalQuery* query,
                                      PlanStageStats* winnerStats,
                                      const vector<PlanStageStats*>& rejectedStats,
                                      BSONObjBuilder* out) {
        BSONObjBuilder plannerBob(out->subobjStart("queryPlanner"));;

        plannerBob.append("plannerVersion", QueryPlanner::kPlannerVersion);

        BSONObjBuilder parsedQueryBob(plannerBob.subobjStart("parsedQuery"));
        query->root()->toBSON(&parsedQueryBob);
        parsedQueryBob.doneFast();

        BSONObjBuilder winningPlanBob(plannerBob.subobjStart("winningPlan"));
        explainStatsTree(*winnerStats, Explain::QUERY_PLANNER, &winningPlanBob);
        winningPlanBob.doneFast();

        // Genenerate array of rejected plans.
        BSONArrayBuilder allPlansBob(plannerBob.subarrayStart("rejectedPlans"));
        for (size_t i = 0; i < rejectedStats.size(); i++) {
            BSONObjBuilder childBob(allPlansBob.subobjStart());
            explainStatsTree(*rejectedStats[i], Explain::QUERY_PLANNER, &childBob);
        }
        allPlansBob.doneFast();

        plannerBob.doneFast();
    }
Exemple #3
0
    // static
    void Explain::generateExecStats(PlanStageStats* stats,
                                    BSONObjBuilder* out) {

        out->appendNumber("nReturned", stats->common.advanced);
        out->appendNumber("executionTimeMillis", stats->common.executionTimeMillis);

        // Flatten the stats tree into a list.
        vector<PlanStageStats*> statsNodes;
        flattenStatsTree(stats, &statsNodes);

        // Iterate over all stages in the tree and get the total number of keys/docs examined.
        // These are just aggregations of information already available in the stats tree.
        size_t totalKeysExamined = 0;
        size_t totalDocsExamined = 0;
        for (size_t i = 0; i < statsNodes.size(); ++i) {

            totalKeysExamined += getKeysExamined(statsNodes[i]->stageType,
                                                 statsNodes[i]->specific.get());
            totalDocsExamined += getDocsExamined(statsNodes[i]->stageType,
                                                 statsNodes[i]->specific.get());
        }

        out->appendNumber("totalKeysExamined", totalKeysExamined);
        out->appendNumber("totalDocsExamined", totalDocsExamined);

        // Add the tree of stages, with individual execution stats for each stage.
        BSONObjBuilder stagesBob(out->subobjStart("executionStages"));
        explainStatsTree(*stats, Explain::EXEC_STATS, &stagesBob);
        stagesBob.doneFast();
    }