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

Merge index scans on identical index if differing bounds for a single field

    • Type: Icon: Improvement Improvement
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Optimization

       

      Given this scenerio,

      db.c.drop()
      db.c.insert({a: 1, b: 1})
      db.c.createIndex({a: 1, b: 1})
      db.c.createIndex({a: 1, c: 1})
      db.c.find({$or: [{a: 1}, {a: {$gt: 2}}], b: 3})

      We produce a candidate plan that looks like

       

      {
              isCached: false,
              stage: 'FETCH',
              inputStage: {
                stage: 'OR',
                inputStages: [
                  {
                    stage: 'IXSCAN',
                    keyPattern: { a: 1, b: 1 },
                    indexName: 'a_1_b_1',
                    isMultiKey: false,
                    multiKeyPaths: { a: [], b: [] },
                    isUnique: false,
                    isSparse: false,
                    isPartial: false,
                    indexVersion: 2,
                    direction: 'forward',
                    indexBounds: { a: [ '[1, 1]' ], b: [ '[3, 3]' ] }
                  },
                  {
                    stage: 'IXSCAN',
                    keyPattern: { a: 1, b: 1 },
                    indexName: 'a_1_b_1',
                    isMultiKey: false,
                    multiKeyPaths: { a: [], b: [] },
                    isUnique: false,
                    isSparse: false,
                    isPartial: false,
                    indexVersion: 2,
                    direction: 'forward',
                    indexBounds: { a: [ '(2, inf.0]' ], b: [ '[3, 3]' ] }
                  }
                ]
              }
            }, 

      With an OR stage that contains two index scan stages on over the same index. A more efficient plan would be one with a single index scan since these bounds can be unioned.

      indexBounds: { a: [ '[1, 1]', '(2, inf.0]' ], b: [ '[3, 3]' ] } 

       

       

            Assignee:
            Unassigned Unassigned
            Reporter:
            ben.shteinfeld@mongodb.com Ben Shteinfeld
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: