HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Mongo count query taking long time though index is being used

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
indexthoughusedmongoquerylongtimebeingcounttaking

Problem

The following count query is taking lot more time than expected though index is being used and keysExamined , docsExamined are also less

query = {'indxed_field': 'x',
 'a': 'test',
 'b': {'$ne': True},
 'c': {'$gte': 100},
 'd': 2}


the query time is varying from 10-30 secs for different values mentioned there.Following is the explain output of same query with find (to get explain)

```
{u'$clusterTime': {u'clusterTime': Timestamp(1554365186, 14),
u'signature': {u'hash': Binary('xxxxxxxxxxxxxx', 0),
u'keyId': 0L}},
u'executionStats': {u'allPlansExecution': [],
u'executionStages': {u'advanced': 16917,
u'alreadyHasObj': 0,
u'docsExamined': 26218,
u'executionTimeMillisEstimate': 11263,
u'filter': {u'$and': [{u'a': {u'$eq': u'test'}},
{u'b': {u'$eq': 2}},
{u'c': {u'$gte': 100}},
{u'$nor': [{u'd': {u'$eq': True}}]}]},
u'inputStage': {u'advanced': 26218,
u'direction': u'forward',
u'dupsDropped': 0,
u'dupsTested': 0,
u'executionTimeMillisEstimate': 40,
u'indexBounds': {u'indxed_field': [u'["x", "y"]']},
u'indexName': u'indxed_field_1',
u'indexVersion': 1,
u'invalidates': 0,
u'isEOF': 1,
u'isMultiKey': False,
u'isPartial': False,
u'isSparse': False,
u'isUnique': False,
u'keyPattern': {u'indxed_field': 1},
u'keysExamined': 26218,
u'multiKeyPaths': {u'indxed_field': []},
u'nReturned': 26218,
u'needTime': 0,
u'needYield': 0,
u'restoreState': 567,
u'saveState': 567,
u'seeks': 1,
u'seenInvalidated': 0,
u'stage': u'IXSCAN',
u'works': 26219},
u'invalidates': 0,
u'isEOF': 1,
u'nReturned': 16917,
u'needTime': 9301,
u'needYield': 0,
u'restoreState': 567,
u'saveState': 567,
u'stage': u'FETCH',
u'works': 26219},
u'execut

Solution

Mongo count query taking long time though index is being used

As per MongoDB documentation here To return information on query plans and execution statistics of the query plans, MongoDB provides:

  • the db.collection.explain()


method,

  • the


cursor.explain() method, and

  • the


explain command.

The explain results present the query plans as a tree of stages.

"winningPlan" : {
   "stage" : ,
   ...
   "inputStage" : {
      "stage" : ,
      ...
      "inputStage" : {
         "stage" : ,
         ...
      }
   }
},


Each stage passes its results (i.e. documents or index keys) to the parent node. The leaf nodes access the collection or the indices. The internal nodes manipulate the documents or the index keys that result from the child nodes. The root node is the final stage from which MongoDB derives the result set.

Stages are descriptive of the operation; e.g.

  • COLLSCAN for a collection scan



  • IXSCAN for scanning index keys



  • FETCH for retrieving documents



  • SHARD_MERGE for merging results from shards



  • SHARDING_FILTER for filtering out orphan documents from shards



explain.executionStats.executionStages.inputStage.keysExamined

For query execution stages that scan an index (e.g. IXSCAN), keysExamined is the total number of in-bounds and out-of-bounds keys that are examined in the process of the index scan. If the index scan consists of a single contiguous range of keys, only in-bounds keys need to be examined. If the index bounds consists of several key ranges, the index scan execution process may examine out-of-bounds keys in order to skip from the end of one range to the beginning of the next.

Consider the following example, where there is an index of field x and the collection contains 100 documents with x values 1 through 100:

db.keys.find( { x : { $in : [ 3, 4, 50, 74, 75, 90 ] } } ).explain( "executionStats" )


The query will scan keys 3 and 4. It will then scan the key 5, detect that it is out-of-bounds, and skip to the next key 50.

Continuing this process, the query scans keys 3, 4, 5, 50, 51, 74, 75, 76, 90, and 91. Keys 5, 51, 76, and 91 are out-of-bounds keys that are still examined. The value of keysExamined is 10.

Note: New in version 3.4: For index scan (IXSCAN) stages only. The number of times that we had to seek the index cursor to a new position in order to complete the index scan.

executionStats

The returned executionStats information details the execution of the winning plan. In order to include executionStats in the results, you must run the explain in either:

  • executionStats


or

  • allPlansExecution


verbosity mode. Use allPlansExecution mode to include partial
execution data captured during plan
selection.

For unsharded collections, explain returns the following executionStats information:

"executionStats" : {
   "executionSuccess" : ,
   "nReturned" : ,
   "executionTimeMillis" : ,
   "totalKeysExamined" : ,
   "totalDocsExamined" : ,
   "executionStages" : {
      "stage" : 
      "nReturned" : ,
      "executionTimeMillisEstimate" : ,
      "works" : ,
      "advanced" : ,
      "needTime" : ,
      "needYield" : ,
      "saveState" : ,
      "restoreState" : ,
      "isEOF" : ,
      ...
      "inputStage" : {
         "stage" : ,
         "nReturned" : ,
         "executionTimeMillisEstimate" : ,
         ...
         "inputStage" : {
            ...
         }
      }
   },
   "allPlansExecution" : [
      {
         "nReturned" : ,
         "executionTimeMillisEstimate" : ,
         "totalKeysExamined" : ,
         "totalDocsExamined" :,
         "executionStages" : {
            "stage" : ,
            "nReturned" : ,
            "executionTimeMillisEstimate" : ,
            ...
            "inputStage" : {
               "stage" : ,
               ...
               "inputStage" : {
                 ...
               }
            }
         }
      },
      ...
   ]
}


When an index covers a query, MongoDB can both match the query conditions and return the results using only the index keys; i.e. MongoDB does not need to examine documents from the collection to return the results.

When an index covers a query, the explain result has an IXSCAN stage that is not a descendant of a FETCH stage, and in the executionStats, the totalDocsExamined is 0.

Code Snippets

"winningPlan" : {
   "stage" : <STAGE1>,
   ...
   "inputStage" : {
      "stage" : <STAGE2>,
      ...
      "inputStage" : {
         "stage" : <STAGE3>,
         ...
      }
   }
},
db.keys.find( { x : { $in : [ 3, 4, 50, 74, 75, 90 ] } } ).explain( "executionStats" )
"executionStats" : {
   "executionSuccess" : <boolean>,
   "nReturned" : <int>,
   "executionTimeMillis" : <int>,
   "totalKeysExamined" : <int>,
   "totalDocsExamined" : <int>,
   "executionStages" : {
      "stage" : <STAGE1>
      "nReturned" : <int>,
      "executionTimeMillisEstimate" : <int>,
      "works" : <int>,
      "advanced" : <int>,
      "needTime" : <int>,
      "needYield" : <int>,
      "saveState" : <int>,
      "restoreState" : <int>,
      "isEOF" : <boolean>,
      ...
      "inputStage" : {
         "stage" : <STAGE2>,
         "nReturned" : <int>,
         "executionTimeMillisEstimate" : <int>,
         ...
         "inputStage" : {
            ...
         }
      }
   },
   "allPlansExecution" : [
      {
         "nReturned" : <int>,
         "executionTimeMillisEstimate" : <int>,
         "totalKeysExamined" : <int>,
         "totalDocsExamined" :<int>,
         "executionStages" : {
            "stage" : <STAGEA>,
            "nReturned" : <int>,
            "executionTimeMillisEstimate" : <int>,
            ...
            "inputStage" : {
               "stage" : <STAGEB>,
               ...
               "inputStage" : {
                 ...
               }
            }
         }
      },
      ...
   ]
}

Context

StackExchange Database Administrators Q#234035, answer score: 3

Revisions (0)

No revisions yet.