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

Consider ixscan plan for comparisons to object literals

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

      Presumably since the index can't fully cover/answer the query, we don't consider any relevant indexes when comparing to sub-objects:

      > db.test.drop()
      true
      > db.test.createIndex({"a.b": 1, "a.c": 1})
      {
              "numIndexesBefore" : 1,
              "numIndexesAfter" : 2,
              "createdCollectionAutomatically" : true,
              "ok" : 1
      }
      > db.test.insert({a: {b: 1, c: 2}})
      WriteResult({ "nInserted" : 1 })
      > db.test.find({a: {b: 1, c: 2}}).explain()
      {
              "explainVersion" : "1",
              "queryPlanner" : {
                      "namespace" : "test.test",
                      "parsedQuery" : {
                              "a" : {
                                      "$eq" : {
                                              "b" : 1,
                                              "c" : 2
                                      }
                              }
                      },
                      "indexFilterSet" : false,
                      "queryHash" : "18A4453A",
                      "planCacheKey" : "E34C8026",
                      "optimizationTimeMillis" : 0,
                      "maxIndexedOrSolutionsReached" : false,
                      "maxIndexedAndSolutionsReached" : false,
                      "maxScansToExplodeReached" : false,
                      "prunedSimilarIndexes" : false,
                      "winningPlan" : {
                              "isCached" : false,
                              "stage" : "COLLSCAN",
                              "filter" : {
                                      "a" : {
                                              "$eq" : {
                                                      "b" : 1,
                                                      "c" : 2
                                              }
                                      }
                              },
                              "direction" : "forward"
                      },
                      "rejectedPlans" : [ ]
              },
              "command" : {
                      "find" : "test",
                      "filter" : {
                              "a" : {
                                      "b" : 1,
                                      "c" : 2
                              }
                      },
                      "$db" : "test"
              },
              "serverInfo" : {
                      "host" : "ip-10-128-16-109",
                      "port" : 27017,
                      "version" : "8.0.0-alpha2",
                      "gitVersion" : "unknown"
              },
              "serverParameters" : {
                      "internalQueryFacetBufferSizeBytes" : 104857600,
                      "internalQueryFacetMaxOutputDocSizeBytes" : 104857600,
                      "internalLookupStageIntermediateDocumentMaxSizeBytes" : 104857600,
                      "internalDocumentSourceGroupMaxMemoryBytes" : 104857600,
                      "internalQueryMaxBlockingSortMemoryUsageBytes" : 104857600,
                      "internalQueryProhibitBlockingMergeOnMongoS" : 0,
                      "internalQueryMaxAddToSetBytes" : 104857600,
                      "internalDocumentSourceSetWindowFieldsMaxMemoryBytes" : 104857600,
                      "internalQueryFrameworkControl" : "trySbeRestricted"
              },
              "ok" : 1
      } 

      However it's possible to generate exact index bounds with a residual equality match on the entire sub-object, which could be far more performant than a collection scan if the predicate is highly selective. Worth noting that in the above example, switching to dotted path notation gives slightly different semantics (allows other fields in the matching sub-object) and will use the index.

            Assignee:
            backlog-query-optimization [DO NOT USE] Backlog - Query Optimization
            Reporter:
            nicholas.zolnierz@mongodb.com Nicholas Zolnierz
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated: