-
Type:
Improvement
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
-
Query Optimization
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Overview
Since PR 10gen/mongo#58846, PlanExplainerImpl takes an isExplain constructor flag (src/mongo/db/query/plan_explainer_impl.cpp, constructor): for explain commands whose MultiPlanStage stays in the execution tree (pure multi-planning), the constructor snapshots the trial statistics before the explained query executes, so the V3 winner display can show trial rather than final-execution counters; normal queries skip that stats-tree deep copy. Review (jameseh96 on PR 10gen/mongo#58846) suggested making this structural instead of flag-driven: the factory is the natural customization point to choose a different PlanExplainer instance, and the V3 machinery could live in its own subclass.
Proposed fix
- Explain-ness is known before the explainer is constructed (query.getExplain()), so plan_explainer_factory::make() (src/mongo/db/query/plan_explainer_factory.cpp) can choose between:
- an explain-specialized subclass (e.g. PlanExplainerImplV3 deriving from PlanExplainerImpl) that owns the construction-time trial-stats snapshot and the V3 per-plan enumerator (_getPlanEntriesV3() becoming a virtual override), and
- the lean base implementation for normal queries, with no isExplain flag and no snapshot.
- The "fallback to legacy" cases keep working through the base-class implementation - either the factory picks the base class when legacy shape is known ahead of construction, or the subclass delegates to the parent implementation when the decision arrives later.
- Delete the isExplain parameter from the constructor and from plan_explainer_factory::make(), including the pass-through in PlanExplainerClassicRuntimePlannerForSBE (src/mongo/db/query/plan_explainer_sbe.cpp), whose embedded classic explainer serves only the legacy accessors and never needs the snapshot.
Note: a pure no-op explainer for non-explain operations is not viable - getPlanSummary()/getSummaryStats() serve every query (slow-query log, profiler, CurOp) - so the split is between "explain-capable" and "summary-only" surfaces, not "explainer vs nothing".
Sequencing
Do this after SERVER-131451 (V3 output for the planSummary/plannerChoice verbosities): that work reshapes the V3 surface the subclass would own, and carving the class boundary before it means carving it twice.
TODO SERVER-NNNNN comments referencing this ticket sit on the PlanExplainerImpl constructor and the factory.
- depends on
-
SERVER-131451 Extend explain V3 plans structure to plannerChoice verbosity
-
- Closed
-
- is related to
-
SERVER-132377 Add reason to the rankerChoice object in explain V3
-
- Closed
-
-
SERVER-132079 Stop sourcing explain content from OpDebug diagnostics state
-
- Needs Scheduling
-