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

The regex filter operation should be applied in the IXSCAN stage if possible

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Open
    • Priority: Major - P3
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: Backlog
    • Component/s: Querying
    • Labels:
      None
    • Case:

      Description

      Currently when an index is multikey the filter step for the regex match gets bumped out of the IXSCAN stage and into the FETCH stage. The logical reason for this is not immediately clear and it seems that this may be unnecessary. The result of this is that we fetch and examine documents that won't match the regex even though we could have concluded that based on information available during the IXSCAN.

      diff:PRIMARY> db.version()
      3.4.3
      diff:PRIMARY> c.createIndex({x:1})
      {
          "createdCollectionAutomatically" : false,
          "numIndexesBefore" : 1,
          "numIndexesAfter" : 2,
          "ok" : 1
      }
      diff:PRIMARY> c.find({x:/1/}).explain().queryPlanner.winningPlan
      {
          "stage" : "FETCH",
          "inputStage" : {
              "stage" : "IXSCAN",
              "filter" : {
                  "x" : {
                      "$regex" : "1"
                  }
              },
              "keyPattern" : {
                  "x" : 1
              },
              "indexName" : "x_1",
              "isMultiKey" : false,
              "multiKeyPaths" : {
                  "x" : [ ]
              },
              "isUnique" : false,
              "isSparse" : false,
              "isPartial" : false,
              "indexVersion" : 2,
              "direction" : "forward",
              "indexBounds" : {
                  "x" : [
                      "[\"\", {})",
                      "[/1/, /1/]"
                  ]
              }
          }
      }
      diff:PRIMARY> c.insert({x:[1,2]})
      WriteResult({ "nInserted" : 1 })
      diff:PRIMARY> c.find({x:/1/}).explain().queryPlanner.winningPlan
      {
          "stage" : "FETCH",
          "filter" : {
              "x" : {
                  "$regex" : "1"
              }
          },
          "inputStage" : {
              "stage" : "IXSCAN",
              "keyPattern" : {
                  "x" : 1
              },
              "indexName" : "x_1",
              "isMultiKey" : true,
              "multiKeyPaths" : {
                  "x" : [
                      "x"
                  ]
              },
              "isUnique" : false,
              "isSparse" : false,
              "isPartial" : false,
              "indexVersion" : 2,
              "direction" : "forward",
              "indexBounds" : {
                  "x" : [
                      "[\"\", {})",
                      "[/1/, /1/]"
                  ]
              }
          }
      }
      

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              backlog-query-optimization Backlog - Query Optimization
              Reporter:
              christopher.harris Christopher Harris
              Participants:
              Votes:
              5 Vote for this issue
              Watchers:
              20 Start watching this issue

                Dates

                Created:
                Updated: