diff options
author | Anton Korshunov <anton.korshunov@mongodb.com> | 2021-01-28 15:52:50 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-02-05 07:21:33 +0000 |
commit | 8fbc7b1b11a15625bc1025d2e30decb5ca2e48b3 (patch) | |
tree | bb0fdfba643c67e44592b68e62f6a7612750c49a /src/mongo | |
parent | 2e376c871e15844736b285b8f68d003a7cf889d0 (diff) | |
download | mongo-8fbc7b1b11a15625bc1025d2e30decb5ca2e48b3.tar.gz |
SERVER-53271 Compute executionTimeMillisEstimates metric for SBE PlanStages
Diffstat (limited to 'src/mongo')
24 files changed, 187 insertions, 0 deletions
diff --git a/src/mongo/db/exec/sbe/stages/branch.cpp b/src/mongo/db/exec/sbe/stages/branch.cpp index 15db672a013..36715084bd9 100644 --- a/src/mongo/db/exec/sbe/stages/branch.cpp +++ b/src/mongo/db/exec/sbe/stages/branch.cpp @@ -106,6 +106,8 @@ value::SlotAccessor* BranchStage::getAccessor(CompileCtx& ctx, value::SlotId slo } void BranchStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _specificStats.numTested++; @@ -132,6 +134,8 @@ void BranchStage::open(bool reOpen) { } PlanState BranchStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (!_activeBranch) { return trackPlanState(PlanState::IS_EOF); } @@ -158,6 +162,8 @@ PlanState BranchStage::getNext() { } void BranchStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; if (_thenOpened) { diff --git a/src/mongo/db/exec/sbe/stages/bson_scan.cpp b/src/mongo/db/exec/sbe/stages/bson_scan.cpp index 6de5c52b659..f3222d6c04a 100644 --- a/src/mongo/db/exec/sbe/stages/bson_scan.cpp +++ b/src/mongo/db/exec/sbe/stages/bson_scan.cpp @@ -82,11 +82,15 @@ value::SlotAccessor* BSONScanStage::getAccessor(CompileCtx& ctx, value::SlotId s } void BSONScanStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _bsonCurrent = _bsonBegin; } PlanState BSONScanStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (_bsonCurrent < _bsonEnd) { if (_recordAccessor) { _recordAccessor->reset(value::TypeTags::bsonObject, @@ -129,6 +133,8 @@ PlanState BSONScanStage::getNext() { } void BSONScanStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; } diff --git a/src/mongo/db/exec/sbe/stages/check_bounds.cpp b/src/mongo/db/exec/sbe/stages/check_bounds.cpp index 539b8e3ffeb..0b8738a95b5 100644 --- a/src/mongo/db/exec/sbe/stages/check_bounds.cpp +++ b/src/mongo/db/exec/sbe/stages/check_bounds.cpp @@ -68,12 +68,16 @@ value::SlotAccessor* CheckBoundsStage::getAccessor(CompileCtx& ctx, value::SlotI } void CheckBoundsStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); _isEOF = false; } PlanState CheckBoundsStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (_isEOF) { return trackPlanState(PlanState::IS_EOF); } @@ -114,6 +118,8 @@ PlanState CheckBoundsStage::getNext() { // passed behind the current interval and need to signal the parent stage that we're // done and can only continue further once the stage is reopened. _isEOF = true; + + ++_specificStats.seeks; break; } } @@ -122,6 +128,8 @@ PlanState CheckBoundsStage::getNext() { } void CheckBoundsStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _children[0]->close(); } diff --git a/src/mongo/db/exec/sbe/stages/co_scan.cpp b/src/mongo/db/exec/sbe/stages/co_scan.cpp index cfa539148ac..99caf7876de 100644 --- a/src/mongo/db/exec/sbe/stages/co_scan.cpp +++ b/src/mongo/db/exec/sbe/stages/co_scan.cpp @@ -45,10 +45,14 @@ value::SlotAccessor* CoScanStage::getAccessor(CompileCtx& ctx, value::SlotId slo } void CoScanStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; } PlanState CoScanStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + checkForInterrupt(_opCtx); // Run forever. @@ -66,6 +70,8 @@ const SpecificStats* CoScanStage::getSpecificStats() const { } void CoScanStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; } diff --git a/src/mongo/db/exec/sbe/stages/exchange.cpp b/src/mongo/db/exec/sbe/stages/exchange.cpp index ed52a7ead43..b6e6602ce69 100644 --- a/src/mongo/db/exec/sbe/stages/exchange.cpp +++ b/src/mongo/db/exec/sbe/stages/exchange.cpp @@ -197,6 +197,8 @@ value::SlotAccessor* ExchangeConsumer::getAccessor(CompileCtx& ctx, value::SlotI return ctx.getAccessor(slot); } void ExchangeConsumer::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; if (reOpen) { @@ -289,6 +291,8 @@ void ExchangeConsumer::open(bool reOpen) { } PlanState ExchangeConsumer::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (_orderPreserving) { // Build a heap and return min element. uasserted(4822834, "ordere exchange not yet implemented"); @@ -321,6 +325,8 @@ PlanState ExchangeConsumer::getNext() { return trackPlanState(PlanState::IS_EOF); } void ExchangeConsumer::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; { @@ -490,6 +496,8 @@ value::SlotAccessor* ExchangeProducer::getAccessor(CompileCtx& ctx, value::SlotI return _children[0]->getAccessor(ctx, slot); } void ExchangeProducer::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; if (reOpen) { uasserted(4822839, "exchange producer cannot be reopened"); @@ -513,6 +521,8 @@ bool ExchangeProducer::appendData(size_t consumerId) { } PlanState ExchangeProducer::getNext() { + auto optTimer(getOptTimer(_opCtx)); + while (_children[0]->getNext() == PlanState::ADVANCED) { // Push to the correct pipe. switch (_state->policy()) { @@ -554,6 +564,8 @@ PlanState ExchangeProducer::getNext() { return trackPlanState(PlanState::IS_EOF); } void ExchangeProducer::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _children[0]->close(); } diff --git a/src/mongo/db/exec/sbe/stages/filter.h b/src/mongo/db/exec/sbe/stages/filter.h index 4d14cd1f20d..66760acf2f5 100644 --- a/src/mongo/db/exec/sbe/stages/filter.h +++ b/src/mongo/db/exec/sbe/stages/filter.h @@ -70,6 +70,8 @@ public: } void open(bool reOpen) final { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; if constexpr (IsConst) { @@ -86,6 +88,8 @@ public: } PlanState getNext() final { + auto optTimer(getOptTimer(_opCtx)); + // The constant filter evaluates the predicate in the open method. if constexpr (IsConst) { if (!_childOpened) { @@ -118,6 +122,8 @@ public: } void close() final { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; if (_childOpened) { diff --git a/src/mongo/db/exec/sbe/stages/hash_agg.cpp b/src/mongo/db/exec/sbe/stages/hash_agg.cpp index 4c4a5b4f132..2424ba019de 100644 --- a/src/mongo/db/exec/sbe/stages/hash_agg.cpp +++ b/src/mongo/db/exec/sbe/stages/hash_agg.cpp @@ -102,6 +102,8 @@ value::SlotAccessor* HashAggStage::getAccessor(CompileCtx& ctx, value::SlotId sl } void HashAggStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); @@ -140,6 +142,8 @@ void HashAggStage::open(bool reOpen) { } PlanState HashAggStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (_htIt == _ht.end()) { _htIt = _ht.begin(); } else { @@ -178,6 +182,8 @@ const SpecificStats* HashAggStage::getSpecificStats() const { } void HashAggStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _ht.clear(); } diff --git a/src/mongo/db/exec/sbe/stages/hash_join.cpp b/src/mongo/db/exec/sbe/stages/hash_join.cpp index 8e5e167f743..e92bbebdab4 100644 --- a/src/mongo/db/exec/sbe/stages/hash_join.cpp +++ b/src/mongo/db/exec/sbe/stages/hash_join.cpp @@ -119,6 +119,8 @@ value::SlotAccessor* HashJoinStage::getAccessor(CompileCtx& ctx, value::SlotId s } void HashJoinStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); // Insert the outer side into the hash table. @@ -152,6 +154,8 @@ void HashJoinStage::open(bool reOpen) { } PlanState HashJoinStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (_htIt != _htItEnd) { ++_htIt; } @@ -183,6 +187,8 @@ PlanState HashJoinStage::getNext() { } void HashJoinStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _children[1]->close(); } diff --git a/src/mongo/db/exec/sbe/stages/ix_scan.cpp b/src/mongo/db/exec/sbe/stages/ix_scan.cpp index 7a5e376ec2f..51402dd7dd6 100644 --- a/src/mongo/db/exec/sbe/stages/ix_scan.cpp +++ b/src/mongo/db/exec/sbe/stages/ix_scan.cpp @@ -170,6 +170,8 @@ void IndexScanStage::doAttachToTrialRunTracker(TrialRunTracker* tracker) { } void IndexScanStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; invariant(_opCtx); @@ -238,6 +240,8 @@ void IndexScanStage::open(bool reOpen) { // TODO SERVER-49385: When the 'prepare()' phase takes the collection lock, it will be // possible to intialize '_ordering' there instead of here. _ordering = entry->ordering(); + + ++_specificStats.seeks; } else { _cursor.reset(); } @@ -247,6 +251,8 @@ void IndexScanStage::open(bool reOpen) { } PlanState IndexScanStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (!_cursor) { return trackPlanState(PlanState::IS_EOF); } @@ -306,6 +312,8 @@ PlanState IndexScanStage::getNext() { } void IndexScanStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _cursor.reset(); diff --git a/src/mongo/db/exec/sbe/stages/limit_skip.cpp b/src/mongo/db/exec/sbe/stages/limit_skip.cpp index 528c9cd5cc3..b09e3e17a9b 100644 --- a/src/mongo/db/exec/sbe/stages/limit_skip.cpp +++ b/src/mongo/db/exec/sbe/stages/limit_skip.cpp @@ -61,6 +61,8 @@ value::SlotAccessor* LimitSkipStage::getAccessor(CompileCtx& ctx, value::SlotId } void LimitSkipStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _isEOF = false; _children[0]->open(reOpen); @@ -73,6 +75,8 @@ void LimitSkipStage::open(bool reOpen) { _current = 0; } PlanState LimitSkipStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (_isEOF || (_limit && _current++ == *_limit)) { return trackPlanState(PlanState::IS_EOF); } @@ -80,6 +84,8 @@ PlanState LimitSkipStage::getNext() { return trackPlanState(_children[0]->getNext()); } void LimitSkipStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _children[0]->close(); } diff --git a/src/mongo/db/exec/sbe/stages/loop_join.cpp b/src/mongo/db/exec/sbe/stages/loop_join.cpp index b8a1b294bec..0205cd9e2f0 100644 --- a/src/mongo/db/exec/sbe/stages/loop_join.cpp +++ b/src/mongo/db/exec/sbe/stages/loop_join.cpp @@ -88,6 +88,8 @@ value::SlotAccessor* LoopJoinStage::getAccessor(CompileCtx& ctx, value::SlotId s } void LoopJoinStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); _outerGetNext = true; @@ -103,6 +105,8 @@ void LoopJoinStage::openInner() { } PlanState LoopJoinStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (_outerGetNext) { auto state = _children[0]->getNext(); if (state != PlanState::ADVANCED) { @@ -143,6 +147,8 @@ PlanState LoopJoinStage::getNext() { } void LoopJoinStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; if (_reOpenInner) { diff --git a/src/mongo/db/exec/sbe/stages/makeobj.cpp b/src/mongo/db/exec/sbe/stages/makeobj.cpp index 330e4358951..7985a27e592 100644 --- a/src/mongo/db/exec/sbe/stages/makeobj.cpp +++ b/src/mongo/db/exec/sbe/stages/makeobj.cpp @@ -126,6 +126,8 @@ void MakeObjStageBase<O>::projectField(UniqueBSONObjBuilder* bob, size_t idx) { template <MakeObjOutputType O> void MakeObjStageBase<O>::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); } @@ -279,6 +281,8 @@ void MakeObjStageBase<MakeObjOutputType::bsonObject>::produceObject() { template <MakeObjOutputType O> PlanState MakeObjStageBase<O>::getNext() { + auto optTimer(getOptTimer(_opCtx)); + auto state = _children[0]->getNext(); if (state == PlanState::ADVANCED) { @@ -289,6 +293,8 @@ PlanState MakeObjStageBase<O>::getNext() { template <MakeObjOutputType O> void MakeObjStageBase<O>::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _children[0]->close(); } diff --git a/src/mongo/db/exec/sbe/stages/project.cpp b/src/mongo/db/exec/sbe/stages/project.cpp index 10cf54e2b2e..3520ca4c603 100644 --- a/src/mongo/db/exec/sbe/stages/project.cpp +++ b/src/mongo/db/exec/sbe/stages/project.cpp @@ -69,11 +69,15 @@ value::SlotAccessor* ProjectStage::getAccessor(CompileCtx& ctx, value::SlotId sl } } void ProjectStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); } PlanState ProjectStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + auto state = _children[0]->getNext(); if (state == PlanState::ADVANCED) { @@ -90,6 +94,8 @@ PlanState ProjectStage::getNext() { } void ProjectStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _children[0]->close(); } diff --git a/src/mongo/db/exec/sbe/stages/scan.cpp b/src/mongo/db/exec/sbe/stages/scan.cpp index d03a591394c..8b3a1052d26 100644 --- a/src/mongo/db/exec/sbe/stages/scan.cpp +++ b/src/mongo/db/exec/sbe/stages/scan.cpp @@ -166,6 +166,8 @@ void ScanStage::doAttachToTrialRunTracker(TrialRunTracker* tracker) { } void ScanStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; invariant(_opCtx); if (!reOpen) { @@ -209,6 +211,8 @@ void ScanStage::open(bool reOpen) { } PlanState ScanStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (!_cursor) { return trackPlanState(PlanState::IS_EOF); } @@ -271,6 +275,8 @@ PlanState ScanStage::getNext() { } void ScanStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _cursor.reset(); _coll.reset(); @@ -463,6 +469,8 @@ void ParallelScanStage::doAttachToOperationContext(OperationContext* opCtx) { } void ParallelScanStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + invariant(_opCtx); invariant(!reOpen, "parallel scan is not restartable"); @@ -524,6 +532,8 @@ boost::optional<Record> ParallelScanStage::nextRange() { } PlanState ParallelScanStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (!_cursor) { _commonStats.isEOF = true; return PlanState::IS_EOF; @@ -587,6 +597,8 @@ PlanState ParallelScanStage::getNext() { } void ParallelScanStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _cursor.reset(); _coll.reset(); _open = false; diff --git a/src/mongo/db/exec/sbe/stages/sort.cpp b/src/mongo/db/exec/sbe/stages/sort.cpp index 291e302d25c..7126dbea9fc 100644 --- a/src/mongo/db/exec/sbe/stages/sort.cpp +++ b/src/mongo/db/exec/sbe/stages/sort.cpp @@ -157,6 +157,8 @@ void SortStage::doAttachToTrialRunTracker(TrialRunTracker* tracker) { } void SortStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + invariant(_opCtx); _commonStats.opens++; _children[0]->open(reOpen); @@ -208,6 +210,8 @@ void SortStage::open(bool reOpen) { } PlanState SortStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + // When the sort spilled data to disk then read back the sorted runs. if (_mergeIt && _mergeIt->more()) { _mergeData = _mergeIt->next(); @@ -219,6 +223,8 @@ PlanState SortStage::getNext() { } void SortStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _mergeIt.reset(); _sorter.reset(); diff --git a/src/mongo/db/exec/sbe/stages/spool.cpp b/src/mongo/db/exec/sbe/stages/spool.cpp index a5bfae94cde..e0a51b28748 100644 --- a/src/mongo/db/exec/sbe/stages/spool.cpp +++ b/src/mongo/db/exec/sbe/stages/spool.cpp @@ -74,6 +74,8 @@ value::SlotAccessor* SpoolEagerProducerStage::getAccessor(CompileCtx& ctx, value } void SpoolEagerProducerStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); @@ -98,6 +100,8 @@ void SpoolEagerProducerStage::open(bool reOpen) { } PlanState SpoolEagerProducerStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (_bufferIt == _buffer->size()) { _bufferIt = 0; } else { @@ -112,6 +116,8 @@ PlanState SpoolEagerProducerStage::getNext() { } void SpoolEagerProducerStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; } @@ -208,6 +214,8 @@ value::SlotAccessor* SpoolLazyProducerStage::getAccessor(CompileCtx& ctx, value: } void SpoolLazyProducerStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); @@ -217,6 +225,8 @@ void SpoolLazyProducerStage::open(bool reOpen) { } PlanState SpoolLazyProducerStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + auto state = _children[0]->getNext(); if (state == PlanState::ADVANCED) { @@ -253,6 +263,8 @@ PlanState SpoolLazyProducerStage::getNext() { } void SpoolLazyProducerStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; } diff --git a/src/mongo/db/exec/sbe/stages/spool.h b/src/mongo/db/exec/sbe/stages/spool.h index 10b34939c6f..995b10076a0 100644 --- a/src/mongo/db/exec/sbe/stages/spool.h +++ b/src/mongo/db/exec/sbe/stages/spool.h @@ -181,11 +181,15 @@ public: } void open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _bufferIt = _buffer->size(); } PlanState getNext() { + auto optTimer(getOptTimer(_opCtx)); + if constexpr (IsStack) { if (_bufferIt != _buffer->size()) { _buffer->erase(_buffer->begin() + _bufferIt); @@ -211,6 +215,8 @@ public: } void close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; } diff --git a/src/mongo/db/exec/sbe/stages/stages.h b/src/mongo/db/exec/sbe/stages/stages.h index 3b2fb96ab2e..e2afedfdbec 100644 --- a/src/mongo/db/exec/sbe/stages/stages.h +++ b/src/mongo/db/exec/sbe/stages/stages.h @@ -233,6 +233,20 @@ public: stage->doAttachToTrialRunTracker(tracker); } + /** + * Force this stage to collect timing info during its execution. Must not be called after + * execution has started. + */ + void markShouldCollectTimingInfo() { + invariant(!_commonStats.executionTimeMillis || *_commonStats.executionTimeMillis == 0); + _commonStats.executionTimeMillis.emplace(0); + + auto stage = static_cast<T*>(this); + for (auto&& child : stage->_children) { + child->markShouldCollectTimingInfo(); + } + } + protected: PlanState trackPlanState(PlanState state) { if (state == PlanState::IS_EOF) { @@ -244,6 +258,19 @@ protected: return state; } + /** + * Returns an optional timer which is used to collect time spent executing the current stage. + * May return boost::none if it is not necessary to collect timing info. + */ + boost::optional<ScopedTimer> getOptTimer(OperationContext* opCtx) { + if (_commonStats.executionTimeMillis && opCtx) { + return {{opCtx->getServiceContext()->getFastClockSource(), + _commonStats.executionTimeMillis.get_ptr()}}; + } + + return boost::none; + } + CommonStats _commonStats; }; diff --git a/src/mongo/db/exec/sbe/stages/text_match.cpp b/src/mongo/db/exec/sbe/stages/text_match.cpp index cd4096d202c..25c2e21c53d 100644 --- a/src/mongo/db/exec/sbe/stages/text_match.cpp +++ b/src/mongo/db/exec/sbe/stages/text_match.cpp @@ -59,11 +59,15 @@ value::SlotAccessor* TextMatchStage::getAccessor(CompileCtx& ctx, value::SlotId } void TextMatchStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); } PlanState TextMatchStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + auto state = _children[0]->getNext(); if (state == PlanState::ADVANCED) { @@ -87,6 +91,8 @@ PlanState TextMatchStage::getNext() { } void TextMatchStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _children[0]->close(); } diff --git a/src/mongo/db/exec/sbe/stages/traverse.cpp b/src/mongo/db/exec/sbe/stages/traverse.cpp index 25fa70a0e70..0d87e043aa3 100644 --- a/src/mongo/db/exec/sbe/stages/traverse.cpp +++ b/src/mongo/db/exec/sbe/stages/traverse.cpp @@ -124,6 +124,8 @@ value::SlotAccessor* TraverseStage::getAccessor(CompileCtx& ctx, value::SlotId s } void TraverseStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); // Do not open the inner child as we do not have values of correlated parameters yet. @@ -140,6 +142,8 @@ void TraverseStage::openInner(value::TypeTags tag, value::Value val) { } PlanState TraverseStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + auto state = _children[0]->getNext(); if (state != PlanState::ADVANCED) { return trackPlanState(state); @@ -250,6 +254,8 @@ bool TraverseStage::traverse(value::SlotAccessor* inFieldAccessor, } void TraverseStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; if (_reOpenInner) { diff --git a/src/mongo/db/exec/sbe/stages/union.cpp b/src/mongo/db/exec/sbe/stages/union.cpp index 12993254c44..b762b063ce3 100644 --- a/src/mongo/db/exec/sbe/stages/union.cpp +++ b/src/mongo/db/exec/sbe/stages/union.cpp @@ -94,6 +94,8 @@ value::SlotAccessor* UnionStage::getAccessor(CompileCtx& ctx, value::SlotId slot } void UnionStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; if (reOpen) { std::queue<UnionBranch> emptyQueue; @@ -109,6 +111,8 @@ void UnionStage::open(bool reOpen) { } PlanState UnionStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + auto state = PlanState::IS_EOF; while (!_remainingBranchesToDrain.empty() && state != PlanState::ADVANCED) { @@ -137,6 +141,8 @@ PlanState UnionStage::getNext() { } void UnionStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _currentStage = nullptr; while (!_remainingBranchesToDrain.empty()) { diff --git a/src/mongo/db/exec/sbe/stages/unique.cpp b/src/mongo/db/exec/sbe/stages/unique.cpp index ac39588d607..a03162ebc35 100644 --- a/src/mongo/db/exec/sbe/stages/unique.cpp +++ b/src/mongo/db/exec/sbe/stages/unique.cpp @@ -56,11 +56,15 @@ value::SlotAccessor* UniqueStage::getAccessor(CompileCtx& ctx, value::SlotId slo } void UniqueStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + ++_commonStats.opens; _children[0]->open(reOpen); } PlanState UniqueStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + while (_children[0]->getNext() == PlanState::ADVANCED) { value::MaterializedRow key{_inKeyAccessors.size()}; size_t idx = 0; @@ -84,6 +88,8 @@ PlanState UniqueStage::getNext() { } void UniqueStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _children[0]->close(); } diff --git a/src/mongo/db/exec/sbe/stages/unwind.cpp b/src/mongo/db/exec/sbe/stages/unwind.cpp index e16397332c7..3616517942a 100644 --- a/src/mongo/db/exec/sbe/stages/unwind.cpp +++ b/src/mongo/db/exec/sbe/stages/unwind.cpp @@ -87,6 +87,8 @@ value::SlotAccessor* UnwindStage::getAccessor(CompileCtx& ctx, value::SlotId slo } void UnwindStage::open(bool reOpen) { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.opens++; _children[0]->open(reOpen); @@ -95,6 +97,8 @@ void UnwindStage::open(bool reOpen) { } PlanState UnwindStage::getNext() { + auto optTimer(getOptTimer(_opCtx)); + if (!_inArray) { do { auto state = _children[0]->getNext(); @@ -151,6 +155,8 @@ PlanState UnwindStage::getNext() { } void UnwindStage::close() { + auto optTimer(getOptTimer(_opCtx)); + _commonStats.closes++; _children[0]->close(); } diff --git a/src/mongo/db/query/stage_builder_util.cpp b/src/mongo/db/query/stage_builder_util.cpp index c3af8b207a9..e9d92bbd6c2 100644 --- a/src/mongo/db/query/stage_builder_util.cpp +++ b/src/mongo/db/query/stage_builder_util.cpp @@ -78,6 +78,12 @@ buildSlotBasedExecutableTree(OperationContext* opCtx, root->attachToOperationContext(opCtx); + auto expCtx = cq.getExpCtxRaw(); + tassert(5327100, "No expression context", expCtx); + if (expCtx->explain || expCtx->mayDbProfile) { + root->markShouldCollectTimingInfo(); + } + // Register this plan to yield according to the configured policy. sbeYieldPolicy->registerPlan(root.get()); |