Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-90554

[v7.0] SBE subplanner writes plan cache entries for each $or branch

    • Type: Icon: Bug Bug
    • Resolution: Won't Do
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Query Planning
    • None
    • Query Optimization
    • ALL
    • Hide

      I wrote the following script which demonstrates the problem when executed against 7.0 (without any setParameters or flags):

      const coll = db.sbe_subplanner_writes_extra_entries;
      coll.drop();
      
      assert.commandWorked(coll.createIndex({a: 1}));
      assert.commandWorked(coll.createIndex({b: 1}));
      assert.commandWorked(coll.createIndex({c: 1}));
      assert.commandWorked(coll.createIndex({d: 1}));
      
      // Set up the data so that the index on "b" is preferable for the first $or clause and the index
      // on "d" is preferable for the second $or clause.
      for (let i = 0; i < 4; ++i) {
          assert.commandWorked(coll.insert({a: 1, b: i, e: i}));
          assert.commandWorked(coll.insert({c: 1, d: i, e: i}));
      }
      
      let pipeline =
          [{$match: {$or: [{a: 1, b: 1}, {c: 1, d: 1}]}}, {$group: {_id: null, avg_f: {$avg: "$e"}}}];
      
      // Clear the plan cache and run the query.
      coll.getPlanCache().clear();
      assert.eq(1, coll.aggregate(pipeline).itcount());
      
      let cacheContents = coll.aggregate([{$planCacheStats: {}}]).toArray();
      for (let entry of cacheContents) {
          assert.eq(entry.version, "2");
          print(entry.cachedPlan.stages);
          print("================")
      }
      
      
      Show
      I wrote the following script which demonstrates the problem when executed against 7.0 (without any setParameters or flags): const coll = db.sbe_subplanner_writes_extra_entries; coll.drop(); assert .commandWorked(coll.createIndex({a: 1})); assert .commandWorked(coll.createIndex({b: 1})); assert .commandWorked(coll.createIndex({c: 1})); assert .commandWorked(coll.createIndex({d: 1})); // Set up the data so that the index on "b" is preferable for the first $or clause and the index // on "d" is preferable for the second $or clause. for (let i = 0; i < 4; ++i) { assert .commandWorked(coll.insert({a: 1, b: i, e: i})); assert .commandWorked(coll.insert({c: 1, d: i, e: i})); } let pipeline = [{$match: {$or: [{a: 1, b: 1}, {c: 1, d: 1}]}}, {$group: {_id: null , avg_f: {$avg: "$e" }}}]; // Clear the plan cache and run the query. coll.getPlanCache().clear(); assert .eq(1, coll.aggregate(pipeline).itcount()); let cacheContents = coll.aggregate([{$planCacheStats: {}}]).toArray(); for (let entry of cacheContents) { assert .eq(entry.version, "2" ); print(entry.cachedPlan.stages); print( "================" ) }

      This bug pertains specifically to the pure SBE subplanner. The code for the SBE subplanner still exists in the master branch. However, it was rendered unused by the work done in PM-3591 (Classic multi-planner with SBE). The affected code cannot be exercised in master and 8.0 unless featureFlagClassicRuntimePlanningForSbe is disabled.

      Furthermore, this bug only applies for versions using the SBE plan cache. Since 6.0 does not use the SBE plan cache, 6.0 is also not affected.

      This is a long way of saying that there is a bug on the 7.0 branch only, since in that branch we both use the pure SBE subplanner and the SBE plan cache. The correct caching behavior for the subplanner with the SBE plan cache is to create a plan cache entry for the entire plan. However, this code means that the implementation on 7.0 will actually create cache entries for each $or branch in addition to a cache entry for the entire query. I've demonstrated this behavior with a short JS repro script.

      This isn't a query correctness problem, but it could lead to unnecessary cache bloat.

      Also note that this problem will go away if we choose to backport PM-3591 to the 7.0 branch.

            Assignee:
            backlog-query-optimization [DO NOT USE] Backlog - Query Optimization
            Reporter:
            david.storch@mongodb.com David Storch
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: