2017-10-10 2 views
1

Je cours Community MongoDB 3.4.9 sur mon ordinateur portable avec 64 Go de RAM. J'ai une collection avec plus de 12 millions de documents. Chaque document a au moins from et to champs de type Int64. Les from - to sont des plages uniques. Il n'y a pas de documents avec des plages de chevauchement. Il existe un index sur la collection comme suit:

{ 
    "v" : NumberInt(1), 
    "unique" : true, 
    "key" : { 
     "from" : NumberInt(1), 
     "to" : NumberInt(1) 
    }, 
    "name" : "range", 
    "ns" : "db.location", 
    "background" : true 
} 

Le serveur/base de données est inactif. Il n'y a pas de clients. Je lance la requête ci-dessous encore et encore et j'obtiens un temps d'exécution constant d'environ 21 secondes.

db.location.find({from:{$lte:NumberLong(3682093364)},to:{$gte:NumberLong(3682093364)}}).limit(1) 

Inversion des conditions and ne fait pas de différence par rapport au temps d'exécution. La commande explain affiche les éléments suivants.

{ 
    "queryPlanner" : { 
     "plannerVersion" : 1.0, 
     "namespace" : "db.location", 
     "indexFilterSet" : false, 
     "parsedQuery" : { 
      "$and" : [ 
       { 
        "from" : { 
         "$lte" : NumberLong(3682093364) 
        } 
       }, 
       { 
        "to" : { 
         "$gte" : NumberLong(3682093364) 
        } 
       } 
      ] 
     }, 
     "winningPlan" : { 
      "stage" : "LIMIT", 
      "limitAmount" : 1.0, 
      "inputStage" : { 
       "stage" : "FETCH", 
       "inputStage" : { 
        "stage" : "IXSCAN", 
        "keyPattern" : { 
         "from" : 1.0, 
         "to" : 1.0 
        }, 
        "indexName" : "range", 
        "isMultiKey" : false, 
        "multiKeyPaths" : { 
         "from" : [ 

         ], 
         "to" : [ 

         ] 
        }, 
        "isUnique" : true, 
        "isSparse" : false, 
        "isPartial" : false, 
        "indexVersion" : 1.0, 
        "direction" : "forward", 
        "indexBounds" : { 
         "from" : [ 
          "[-inf.0, 3682093364]" 
         ], 
         "to" : [ 
          "[3682093364, inf.0]" 
         ] 
        } 
       } 
      } 
     }, 
     "rejectedPlans" : [ 

     ] 
    }, 
    "executionStats" : { 
     "executionSuccess" : true, 
     "nReturned" : 1.0, 
     "executionTimeMillis" : 21526.0, 
     "totalKeysExamined" : 12284007.0, 
     "totalDocsExamined" : 1.0, 
     "executionStages" : { 
      "stage" : "LIMIT", 
      "nReturned" : 1.0, 
      "executionTimeMillisEstimate" : 20945.0, 
      "works" : 12284008.0, 
      "advanced" : 1.0, 
      "needTime" : 12284006.0, 
      "needYield" : 0.0, 
      "saveState" : 96299.0, 
      "restoreState" : 96299.0, 
      "isEOF" : 1.0, 
      "invalidates" : 0.0, 
      "limitAmount" : 1.0, 
      "inputStage" : { 
       "stage" : "FETCH", 
       "nReturned" : 1.0, 
       "executionTimeMillisEstimate" : 20714.0, 
       "works" : 12284007.0, 
       "advanced" : 1.0, 
       "needTime" : 12284006.0, 
       "needYield" : 0.0, 
       "saveState" : 96299.0, 
       "restoreState" : 96299.0, 
       "isEOF" : 0.0, 
       "invalidates" : 0.0, 
       "docsExamined" : 1.0, 
       "alreadyHasObj" : 0.0, 
       "inputStage" : { 
        "stage" : "IXSCAN", 
        "nReturned" : 1.0, 
        "executionTimeMillisEstimate" : 20357.0, 
        "works" : 12284007.0, 
        "advanced" : 1.0, 
        "needTime" : 12284006.0, 
        "needYield" : 0.0, 
        "saveState" : 96299.0, 
        "restoreState" : 96299.0, 
        "isEOF" : 0.0, 
        "invalidates" : 0.0, 
        "keyPattern" : { 
         "from" : 1.0, 
         "to" : 1.0 
        }, 
        "indexName" : "range", 
        "isMultiKey" : false, 
        "multiKeyPaths" : { 
         "from" : [ 

         ], 
         "to" : [ 

         ] 
        }, 
        "isUnique" : true, 
        "isSparse" : false, 
        "isPartial" : false, 
        "indexVersion" : 1.0, 
        "direction" : "forward", 
        "indexBounds" : { 
         "from" : [ 
          "[-inf.0, 3682093364]" 
         ], 
         "to" : [ 
          "[3682093364, inf.0]" 
         ] 
        }, 
        "keysExamined" : 12284007.0, 
        "seeks" : 12284007.0, 
        "dupsTested" : 0.0, 
        "dupsDropped" : 0.0, 
        "seenInvalidated" : 0.0 
       } 
      } 
     }, 
     "allPlansExecution" : [ 

     ] 
    }, 
    "serverInfo" : { 
     "host" : "LAPTOP-Q96TVSN8", 
     "port" : 27017.0, 
     "version" : "3.4.9", 
     "gitVersion" : "876ebee8c7dd0e2d992f36a848ff4dc50ee6603e" 
    }, 
    "ok" : 1.0 
} 

La fourniture d'un hint ne fait pas de différence. explain semble indiquer que l'index correct (et unique) est déjà utilisé mais que la majeure partie du temps d'exécution (20s) est passée à IXSCAN. Le journal MongoDB indique que de nombreux éléments d'index ont été analysés, mais qu'un seul document a été touché et renvoyé. Il montre également un nombre fou de verrous et de rendements considérant qu'il y a ZÉRO opérations concurrentes sur la base de données. Le moteur sous-jacent est wiredTiger sur un disque SSD. L'utilisation de la mémoire MongoDB est de 7 Go.

2017-10-10T10:06:14.456+0200 I COMMAND [conn33] command db.location appName: "MongoDB Shell" command: explain { explain: { find: "location", filter: { from: { $lte: 3682093364 }, to: { $gte: 3682093364 } }, limit: 1.0, singleBatch: false }, verbosity: "allPlansExecution" } numYields:96299 reslen:1944 locks:{ Global: { acquireCount: { r: 192600 } }, Database: { acquireCount: { r: 96300 } }, Collection: { acquireCount: { r: 96300 } } } protocol:op_command 21526ms 

Y at-il une meilleure façon de structurer le document afin que les recherches sont plus rapides compte tenu de mon gammes ne sont jamais chevauchement? Y at-il quelque chose d'évident que je fais mal?

MISE À JOUR:

Lorsque je laisse tomber l'indice, COLLSCAN est utilisé et le document se trouve dans 8-9 secondes cohérentes.

Répondre

0

Je déteste répondre à mes propres questions mais là encore je suis heureux de trouver la solution.

Même s'il est logique de créer un tel indice composite, en considérant les spécificités des plages sans chevauchement, il s'avère que la portée de la recherche est trop large. Plus le nombre d'entrées est élevé, plus il faudra de temps pour trouver le résultat car de plus en plus d'entrées d'index satisfont from <= number et le dernier résultat dans l'étendue de recherche est en fait celui que nous recherchons (l'index est scanné de gauche à droite) . La solution consiste à modifier l'indice pour qu'il soit { from: -1 } ou { to: 1 }. L'index composite n'est vraiment pas nécessaire dans ce scénario car les plages ne se chevauchent pas et le tout premier document trouvé par l'index est le même document renvoyé. Ceci est maintenant rapide comme prévu.

Vous vivez et apprendre ...