1
// @file explain.h - Helper classes for generating query explain output.
3
/* Copyright 2012 10gen Inc.
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
* you may not use this file except in compliance with the License.
7
* You may obtain a copy of the License at
9
* http://www.apache.org/licenses/LICENSE-2.0
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
21
#include "../util/timer.h"
26
* Note: by default we filter out allPlans and oldPlan in the shell's
27
* explain() function. If you add any recursive structures, make sure to
28
* edit the JS to make sure everything gets filtered.
31
/** The timer starts on construction and provides the duration since then or until stopped. */
34
DurationTimer() : _running( true ), _duration() {}
35
void stop() { _running = false; _duration = _timer.millis(); }
36
int duration() const { return _running ? _timer.millis() : _duration; }
43
class ExplainClauseInfo;
45
/** Data describing execution of a query plan. */
46
class ExplainPlanInfo {
50
/** Note information about the plan. */
51
void notePlan( const Cursor &cursor, bool scanAndOrder, bool indexOnly );
52
/** Note an iteration of the plan. */
53
void noteIterate( bool match, bool loadedRecord, const Cursor &cursor );
54
/** Note that the plan finished execution. */
55
void noteDone( const Cursor &cursor );
56
/** Note that the plan was chosen over others by the query optimizer. */
59
/** BSON summary of the plan. */
61
/** Combined details of both the plan and its clause. */
62
BSONObj pickedPlanBson( const ExplainClauseInfo &clauseInfo ) const;
64
bool picked() const { return _picked; }
65
bool done() const { return _done; }
66
long long n() const { return _n; }
67
long long nscannedObjects() const { return _nscannedObjects; }
68
long long nscanned() const { return _nscanned; }
71
void noteCursorUpdate( const Cursor &cursor );
75
long long _nscannedObjects;
85
/** Data describing execution of a query clause. */
86
class ExplainClauseInfo {
90
/** Note an iteration of the clause. */
91
void noteIterate( bool match, bool loadedRecord, bool chunkSkip );
92
/** Note a yield for the clause. */
94
/** Revise the total number of documents returned to match an external count. */
95
void reviseN( long long n );
96
/** Stop the clauses's timer. */
99
/** Add information about a plan to this clause. */
100
void addPlanInfo( const shared_ptr<ExplainPlanInfo> &info );
101
BSONObj bson() const;
103
long long n() const { return _n; }
104
long long nscannedObjects() const;
105
long long nscanned() const;
106
long long nscannedObjectsAllPlans() const { return _nscannedObjects; }
107
long long nscannedAllPlans() const;
108
long long nChunkSkips() const { return _nChunkSkips; }
109
int nYields() const { return _nYields; }
110
int millis() const { return _timer.duration(); }
114
* @return Plan explain information to be displayed at the top of the explain output. A
115
* picked() plan will be returned if one is available, otherwise a successful non picked()
116
* plan will be returned.
118
const ExplainPlanInfo &virtualPickedPlan() const;
119
list<shared_ptr<const ExplainPlanInfo> > _plans;
121
long long _nscannedObjects;
122
long long _nChunkSkips;
124
DurationTimer _timer;
127
/** Data describing execution of a query. */
128
class ExplainQueryInfo {
130
/** Note an iteration of the query's current clause. */
131
void noteIterate( bool match, bool loadedRecord, bool chunkSkip );
132
/** Note a yield of the query's current clause. */
134
/** Revise the number of documents returned by the current clause. */
135
void reviseN( long long n );
137
/* Additional information describing the query. */
138
struct AncillaryInfo {
141
void setAncillaryInfo( const AncillaryInfo &ancillaryInfo );
143
/* Add information about a clause to this query. */
144
void addClauseInfo( const shared_ptr<ExplainClauseInfo> &info );
145
BSONObj bson() const;
148
static string server();
150
list<shared_ptr<ExplainClauseInfo> > _clauses;
151
AncillaryInfo _ancillaryInfo;
152
DurationTimer _timer;
155
/** Data describing execution of a query with a single clause and plan. */
156
class ExplainSinglePlanQueryInfo {
158
ExplainSinglePlanQueryInfo();
160
/** Note information about the plan. */
161
void notePlan( const Cursor &cursor, bool scanAndOrder, bool indexOnly ) {
162
_planInfo->notePlan( cursor, scanAndOrder, indexOnly );
164
/** Note an iteration of the plan and the clause. */
165
void noteIterate( bool match, bool loadedRecord, bool chunkSkip, const Cursor &cursor ) {
166
_planInfo->noteIterate( match, loadedRecord, cursor );
167
_queryInfo->noteIterate( match, loadedRecord, chunkSkip );
169
/** Note a yield for the clause. */
171
_queryInfo->noteYield();
173
/** Note that the plan finished execution. */
174
void noteDone( const Cursor &cursor ) {
175
_planInfo->noteDone( cursor );
178
/** Return the corresponding ExplainQueryInfo for further use. */
179
shared_ptr<ExplainQueryInfo> queryInfo() const {
184
shared_ptr<ExplainPlanInfo> _planInfo;
185
shared_ptr<ExplainQueryInfo> _queryInfo;