Details
-
Bug
-
Resolution: Fixed
-
Major - P3
-
None
-
Fully Compatible
-
ALL
-
Query Optimization 2021-02-22, Query Optimization 2021-03-08
Description
When we have a plan like this:
Count
|
|
|
|
|
MultiPlanStage
|
| |
|
| |
|
other stage yet another stage
|
Running explain() on the plan will "forget" to report about any stage above the MultiPlanStage. The cause of this problem is this code which is used when trying to explain the winning plan here. The questionable code searches the entire plan tree for a MultiPlanStage, and then returns whichever child of it is considered the "winning plan," discarding any stages above.
I think the correct behavior would be to instead "replace" any MultiPlanStage with its best child.
Here's a way of reproducing this (notice the explain output doesn't have a "COUNT" stage).
(function() {
|
"use strict";
|
|
|
var coll = db.record_store_count;
|
coll.drop();
|
|
|
assert.writeOK(coll.insert({x: 0}));
|
assert.writeOK(coll.insert({x: 1}));
|
|
|
assert.commandWorked(coll.ensureIndex({x: 1}));
|
assert.commandWorked(coll.ensureIndex({y: 1}));
|
|
|
let explain = coll.explain("allPlansExecution").find({x: {$in: [1,3]}, y: {$in: [1, 3]}}).count();
|
print("The full explain output is..." + tojson(explain));
|
})();
|
resmoke.py --suites=core count-bug.js
To see what the correct output would be, you can comment out one of the ensureIndex calls. This will mean only one plan is available, and so no MultiPlanStage will be used.