While looking at the QLOG output, I noticed that one of the solutions doesn't have the KEEP_MUTATIONS stage. It seems erroneous, as the code in planner_analysis.cpp doesn't imply any obvious exception for this index.
> db.contact.insert({_id:10,oId:100}) WriteResult({ "nInserted" : 1 }) > db.contact.insert({_id:11,oId:1234}) WriteResult({ "nInserted" : 1 }) > db.contact.insert({_id:12,oId:1234}) WriteResult({ "nInserted" : 1 }) > db.contact.insert({_id:13,oId:100}) WriteResult({ "nInserted" : 1 }) > db.contact.ensureIndex({ organizationId: 1.0, externalId: 1.0, _id: 1.0 }) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.adminCommand({setParameter: 1, verboseQueryLogging: true}) { "was" : false, "ok" : 1 } > db.contact.find({ _id: { $in: [ 11 ] }, organizationId: { $ne: 100 } } ) { "_id" : 11, "oId" : 1234 }
QLOG output:
2014-11-04T20:35:25.843-0500 [conn3] build index on: test.contact properties: { v: 1, key: { organizationId: 1.0, externalId: 1.0, _id: 1.0 }, name: "organizationId_1_externalId_1__id_1", ns: "test.contact" } 2014-11-04T20:35:25.845-0500 [conn3] building index using bulk method 2014-11-04T20:35:25.846-0500 [conn3] build index done. scanned 4 total records. 0.003 secs 2014-11-04T20:36:37.769-0500 [clientcursormon] mem (MB) res:10 virt:2826 2014-11-04T20:36:37.769-0500 [clientcursormon] mapped (incl journal view):320 2014-11-04T20:36:37.769-0500 [clientcursormon] connections:1 2014-11-04T20:37:01.897-0500 [conn3] [QLOG] Running query: ns=test.contact limit=0 skip=0 Tree: $and $not organizationId == 100.0 _id $in [ 11.0 ] Sort: {} Proj: {} 2014-11-04T20:37:01.897-0500 [conn3] [QLOG] Beginning planning... ============================= Options = INDEX_INTERSECTION KEEP_MUTATIONS Canonical query: ns=test.contact limit=0 skip=0 Tree: $and $not organizationId == 100.0 _id $in [ 11.0 ] Sort: {} Proj: {} ============================= 2014-11-04T20:37:01.898-0500 [conn3] [QLOG] Index 0 is kp: { _id: 1 } io: { v: 1, key: { _id: 1 }, name: "_id_", ns: "test.contact" } 2014-11-04T20:37:01.898-0500 [conn3] [QLOG] Index 1 is kp: { organizationId: 1.0, externalId: 1.0, _id: 1.0 } io: { v: 1, key: { organizationId: 1.0, externalId: 1.0, _id: 1.0 }, name: "organizationId_1_externalId_1__id_1", ns: "test.contact" } 2014-11-04T20:37:01.898-0500 [conn3] [QLOG] Predicate over field 'organizationId' 2014-11-04T20:37:01.898-0500 [conn3] [QLOG] Predicate over field '_id' 2014-11-04T20:37:01.898-0500 [conn3] [QLOG] Relevant index 0 is kp: { _id: 1 } io: { v: 1, key: { _id: 1 }, name: "_id_", ns: "test.contact" } 2014-11-04T20:37:01.898-0500 [conn3] [QLOG] Relevant index 1 is kp: { organizationId: 1.0, externalId: 1.0, _id: 1.0 } io: { v: 1, key: { organizationId: 1.0, externalId: 1.0, _id: 1.0 }, name: "organizationId_1_externalId_1__id_1", ns: "test.contact" } 2014-11-04T20:37:01.899-0500 [conn3] [QLOG] Rated tree: $and $not organizationId == 100.0 || First: 1 notFirst: full path: organizationId _id $in [ 11.0 ] || First: 0 notFirst: 1 full path: _id 2014-11-04T20:37:01.899-0500 [conn3] [QLOG] Tagging memoID 1 2014-11-04T20:37:01.899-0500 [conn3] [QLOG] Enumerator: memo just before moving: 2014-11-04T20:37:01.899-0500 [conn3] [QLOG] About to build solntree from tagged tree: $and _id $in [ 11.0 ] || Selected Index #0 pos 0 $not organizationId == 100.0 2014-11-04T20:37:01.899-0500 [conn3] [QLOG] Planner: adding solution: KEEP_MUTATIONS ---filter: $and $not organizationId == 100.0 _id $in [ 11.0 ] ---fetched = 1 ---sortedByDiskLoc = 0 ---getSort = [] ---Child: ------FETCH ---------filter: $not organizationId == 100.0 ---------fetched = 1 ---------sortedByDiskLoc = 1 ---------getSort = [{ _id: 1 }, ] ---------Child: ------------IXSCAN ---------------keyPattern = { _id: 1 } ---------------direction = 1 ---------------bounds = field #0['_id']: [11.0, 11.0] ---------------fetched = 0 ---------------sortedByDiskLoc = 1 ---------------getSort = [{ _id: 1 }, ] 2014-11-04T20:37:01.900-0500 [conn3] [QLOG] Tagging memoID 1 2014-11-04T20:37:01.900-0500 [conn3] [QLOG] Enumerator: memo just before moving: 2014-11-04T20:37:01.900-0500 [conn3] [QLOG] About to build solntree from tagged tree: $and $not organizationId == 100.0 || Selected Index #1 pos 0 _id $in [ 11.0 ] || Selected Index #1 pos 2 2014-11-04T20:37:01.900-0500 [conn3] [QLOG] Planner: adding solution: FETCH ---fetched = 1 ---sortedByDiskLoc = 0 ---getSort = [{ organizationId: 1 }, { organizationId: 1, externalId: 1 }, { organizationId: 1, externalId: 1, _id: 1 }, ] ---Child: ------IXSCAN ---------keyPattern = { organizationId: 1.0, externalId: 1.0, _id: 1.0 } ---------direction = 1 ---------bounds = field #0['organizationId']: [MinKey, 100.0), (100.0, MaxKey], field #1['externalId']: [MinKey, MaxKey], field #2['_id']: [11.0, 11.0] ---------fetched = 0 ---------sortedByDiskLoc = 0 ---------getSort = [{ organizationId: 1 }, { organizationId: 1, externalId: 1 }, { organizationId: 1, externalId: 1, _id: 1 }, ] 2014-11-04T20:37:01.900-0500 [conn3] [QLOG] Planner: outputted 2 indexed solutions. 2014-11-04T20:37:01.901-0500 [conn3] [QLOG] Scoring plan 0: KEEP_MUTATIONS ---filter: $and $not organizationId == 100.0 _id $in [ 11.0 ] ---fetched = 1 ---sortedByDiskLoc = 0 ---getSort = [] ---Child: ------FETCH ---------filter: $not organizationId == 100.0 ---------fetched = 1 ---------sortedByDiskLoc = 1 ---------getSort = [{ _id: 1 }, ] ---------Child: ------------IXSCAN ---------------keyPattern = { _id: 1 } ---------------direction = 1 ---------------bounds = field #0['_id']: [11.0, 11.0] ---------------fetched = 0 ---------------sortedByDiskLoc = 1 ---------------getSort = [{ _id: 1 }, ] Stats: { "type" : "KEEP_MUTATIONS", "works" : 2, "yields" : 0, "unyields" : 0, "invalidates" : 0, "advanced" : 1, "needTime" : 0, "needFetch" : 0, "isEOF" : 1, "children" : [ { "type" : "FETCH", "works" : 2, "yields" : 0, "unyields" : 0, "invalidates" : 0, "advanced" : 1, "needTime" : 0, "needFetch" : 0, "isEOF" : 1, "alreadyHasObj" : 0, "forcedFetches" : 0, "matchTested" : 1, "children" : [ { "type" : "IXSCAN", "works" : 2, "yields" : 0, "unyields" : 0, "invalidates" : 0, "advanced" : 1, "needTime" : 0, "needFetch" : 0, "isEOF" : 1, "keyPattern" : "{ _id: 1 }", "isMultiKey" : 0, "boundsVerbose" : "field #0['_id']: [11.0, 11.0]", "yieldMovedCursor" : 0, "dupsTested" : 0, "dupsDropped" : 0, "seenInvalidated" : 0, "matchTested" : 0, "keysExamined" : 1, "children" : [] } ] } ] } 2014-11-04T20:37:01.901-0500 [conn3] [QLOG] score(1.5003) = baseScore(1) + productivity((1 advanced)/(2 works + 0 needFetch) = 0.5) + tieBreakers(0.0001 noFetchBonus + 0.0001 noSortBonus + 0.0001 noIxisectBonus = 0.0003) 2014-11-04T20:37:01.901-0500 [conn3] [QLOG] score = 1.5003 2014-11-04T20:37:01.901-0500 [conn3] [QLOG] Adding +1 EOF bonus to score. 2014-11-04T20:37:01.902-0500 [conn3] [QLOG] Scoring plan 1: FETCH ---fetched = 1 ---sortedByDiskLoc = 0 ---getSort = [{ organizationId: 1 }, { organizationId: 1, externalId: 1 }, { organizationId: 1, externalId: 1, _id: 1 }, ] ---Child: ------IXSCAN ---------keyPattern = { organizationId: 1.0, externalId: 1.0, _id: 1.0 } ---------direction = 1 ---------bounds = field #0['organizationId']: [MinKey, 100.0), (100.0, MaxKey], field #1['externalId']: [MinKey, MaxKey], field #2['_id']: [11.0, 11.0] ---------fetched = 0 ---------sortedByDiskLoc = 0 ---------getSort = [{ organizationId: 1 }, { organizationId: 1, externalId: 1 }, { organizationId: 1, externalId: 1, _id: 1 }, ] Stats: { "type" : "FETCH", "works" : 2, "yields" : 0, "unyields" : 0, "invalidates" : 0, "advanced" : 1, "needTime" : 1, "needFetch" : 0, "isEOF" : 0, "alreadyHasObj" : 0, "forcedFetches" : 0, "matchTested" : 0, "children" : [ { "type" : "IXSCAN", "works" : 2, "yields" : 0, "unyields" : 0, "invalidates" : 0, "advanced" : 1, "needTime" : 1, "needFetch" : 0, "isEOF" : 0, "keyPattern" : "{ organizationId: 1.0, externalId: 1.0, _id: 1.0 }", "isMultiKey" : 0, "boundsVerbose" : "field #0['organizationId']: [MinKey, 100.0), (100.0, MaxKey], field #1['externalId']: [MinKey, MaxKey], field #2['_id']: [11.0, 11.0]", "yieldMovedCursor" : 0, "dupsTested" : 0, "dupsDropped" : 0, "seenInvalidated" : 0, "matchTested" : 0, "keysExamined" : 2, "children" : [] } ] } 2014-11-04T20:37:01.902-0500 [conn3] [QLOG] score(1.5003) = baseScore(1) + productivity((1 advanced)/(2 works + 0 needFetch) = 0.5) + tieBreakers(0.0001 noFetchBonus + 0.0001 noSortBonus + 0.0001 noIxisectBonus = 0.0003) 2014-11-04T20:37:01.902-0500 [conn3] [QLOG] score = 1.5003 2014-11-04T20:37:01.902-0500 [conn3] [QLOG] Winning solution: KEEP_MUTATIONS ---filter: $and $not organizationId == 100.0 _id $in [ 11.0 ] ---fetched = 1 ---sortedByDiskLoc = 0 ---getSort = [] ---Child: ------FETCH ---------filter: $not organizationId == 100.0 ---------fetched = 1 ---------sortedByDiskLoc = 1 ---------getSort = [{ _id: 1 }, ] ---------Child: ------------IXSCAN ---------------keyPattern = { _id: 1 } ---------------direction = 1 ---------------bounds = field #0['_id']: [11.0, 11.0] ---------------fetched = 0 ---------------sortedByDiskLoc = 1 ---------------getSort = [{ _id: 1 }, ] 2014-11-04T20:37:01.902-0500 [conn3] [QLOG] Not caching runner but returning 1 results.
- is related to
-
SERVER-20299 Delete KEEP_MUTATIONS stage
- Closed