2016-05-19 11 views
1

Ich habe diese Art von einfacher AggregatabfrageGesamtabfrageleistung Sortierung nach isodate

db.SomeCollection.aggregate([{ 
    "$match": { 
    "Id": "someId" 
    } 
}, { 
    "$sort": { 
    "someISODatePropertyName": 1 
    } 
}, { 
    "$unwind": { 
    "path": "$somePropertyName" 
    } 
}], { 
    allowDiskUse: true 
}) 

diese Abfrage gibt 50 Elemente höchstens und dauert 10 Sekunden.

Wenn ich einfach die Art Eigenschaft mit einem numerischen einem ändern: abzuschließen wenigen Millisekunden dauert

db.SomeCollection.aggregate([{ 
    "$match": { 
    "Id": "someId" 
    } 
}, { 
    "$sort": { 
    "someNumericPropertyName": 1 
    } 
}, { 
    "$unwind": { 
    "path": "$somePropertyName" 
    } 
}], { 
    allowDiskUse: true 
}) 

die Abfrage.

Gibt es ein Sortierproblem mit ISODate-Eigenschaften?

Ich kann wirklich nicht verstehen, warum es in der ersten Version so lange dauert.

Vielen Dank.

UPDATE

dies ist das Abfrageergebnis mit "erklären" Flag auf true gesetzt (Anmerkung: auf dem isodate Feld ein Index ist):

{ 
    "waitedMS" : NumberLong(0), 
    "stages" : [ 
     { 
      "$cursor" : { 
       "query" : { 
        "StreamId" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed" 
       }, 
       "sort" : { 
        "CommitStamp" : 1 
       }, 
       "queryPlanner" : { 
        "plannerVersion" : 1, 
        "namespace" : "vrp-events-prod.Commits", 
        "indexFilterSet" : false, 
        "parsedQuery" : { 
         "StreamId" : { 
          "$eq" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed" 
         } 
        }, 
        "winningPlan" : { 
         "stage" : "FETCH", 
         "filter" : { 
          "StreamId" : { 
           "$eq" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed" 
          } 
         }, 
         "inputStage" : { 
          "stage" : "IXSCAN", 
          "keyPattern" : { 
           "CommitStamp" : 1 
          }, 
          "indexName" : "CommitStamp_Index", 
          "isMultiKey" : false, 
          "isUnique" : false, 
          "isSparse" : false, 
          "isPartial" : false, 
          "indexVersion" : 1, 
          "direction" : "forward", 
          "indexBounds" : { 
           "CommitStamp" : [ 
            "[MinKey, MaxKey]" 
           ] 
          } 
         } 
        }, 
        "rejectedPlans" : [] 
       } 
      } 
     }, 
     { 
      "$unwind" : { 
       "path" : "$Events" 
      } 
     } 
    ], 
    "ok" : 1 
} 

Antwort

0

Nach meiner Erfahrung Datum Sortierung ohne Ein Index für das Datumsfeld ist langsam. Wenn Sie davon ausgehen, dass Sie häufig und in der Regel nach Datum aus dieser Sammlung lesen, ist das Hinzufügen eines Index die ideale Lösung.

db.collection.createIndex ("someISODatePropertyName": 1 oder -1)

Versuchen Sie es, es machte immer einen großen Unterschied für mich.

Update:

Unter der Annahme, dass dies nicht verlangsamt Ihre Schreibabfragen zu viel, fügen Sie einen Index, der sowohl über das Spiel und die Art umfasst:

db.xxx.createIndex ({“ StreamId ": 1," CommitStamp ": 1});

Ich testete dies auf meiner Sammlung und es beschleunigt die Abfrage von 15 Sekunden (mit dem Datumsindex) auf weniger als eine Sekunde (mit dem neu erstellten Index). FYI, mein aktualisiert erklären zeigt:

"queryPlanner" : { 
             "plannerVersion" : 1, 
             "namespace" : "db.xxx", 
             "indexFilterSet" : false, 
             "parsedQuery" : { 
               "id" : { 
                 "$eq" : 122 
               } 
             }, 
             "winningPlan" : { 
               "stage" : "FETCH", 
               "inputStage" : { 
                 "stage" : "IXSCAN", 
                 "keyPattern" : { 
                   "id" : 1, 
                   "date" : 1 
                 }, 
                 "indexName" : "id_1_date_1", 
                 "isMultiKey" : false, 
                 "direction" : "forward", 
                 "indexBounds" : { 
                   "id" : [ 
                     "[122.0, 122.0]" 
                   ], 
                   "date" : [ 
                     "[MinKey, MaxKey]" 
                   ] 
                 } 
               } 
             }, 
             "rejectedPlans" : [ ] 
           } 
+1

ja, ich vergaß zu erwähnen, dass ich schon auf diesem Feld einen Index haben (und btw nicht auf dem numerischen ...) , was ich so seltsam finde ist die dramatische Performance-Unterschied zwischen einem numerischen Feld und einem Datumsfeld während einer einfachen Sortieroperation –

+0

Ich denke über die Lösung nach. Ich bin überrascht, dass der Index nicht ausreicht. Können Sie versuchen, Ihre Abfragen mit explain als Option auszuführen und zu sehen, was es sagt? https://docs.mongodb.com/v3.0/reference/method/db.collection.aggregate/ – Tiramisu

+1

Danke, Ich aktualisierte den Beitrag mit dem Explain-Abfrage-Ergebnis. –