2015-04-15 13 views
12

Poniżej kwerendy agregacji:Jak przyspieszyć zapytania agregacyjne?

[ 
    { 
    "$match": { 
     "UserId": { 
     "$in": [ 
      5 
     ] 
     }, 
     "WorkflowStartTime": { 
     "$gte": ISODate('2015-04-09T00:00:00.000Z'), 
     "$lte": ISODate('2015-04-16T00:00:00.000Z') 
     } 
    } 
    }, 
    { 
    "$group": { 
     "_id": { 
     "Task": "$TaskId", 
     "WorkflowId": "$WorkflowInstanceId" 
     }, 
     "TaskName": { 
     "$first": "$Task" 
     }, 
     "StartTime": { 
     "$first": "$StartTime" 
     }, 
     "EndTime": { 
     "$last": "$EndTime" 
     }, 
     "LastExecutionTime": { 
     "$last": "$StartTime" 
     }, 
     "WorkflowName": { 
     "$first": "$WorkflowName" 
     } 
    } 
    }, 
    { 
    "$project": { 
     "_id": 1, 
     "LastExecutionTime": 1, 
     "TaskName": 1, 
     "AverageExecutionTime": { 
     "$subtract": [ 
      "$EndTime", 
      "$StartTime" 
     ] 
     }, 
     "WorkflowName": 1 
    } 
    }, 
    { 
    "$group": { 
     "_id": "$_id.Task", 
     "LastExecutionTime": { 
     "$last": "$LastExecutionTime" 
     }, 
     "AverageExecutionTime": { 
     "$avg": "$AverageExecutionTime" 
     }, 
     "TaskName": { 
     "$first": "$TaskName" 
     }, 
     "TotalInstanceCount": { 
     "$sum": 1 
     }, 
     "WorkflowName": { 
     "$first": "$WorkflowName" 
     } 
    } 
    }, 
    { 
    "$project": { 
     "Id": "$_id", 
     "_id": 0, 
     "Name": "$TaskName", 
     "LastExecutionDate": { 
     "$substr": [ 
      "$LastExecutionTime", 
      0, 
      30 
     ] 
     }, 
     "AverageExecutionTimeInMilliSeconds": "$AverageExecutionTime", 
     "TotalInstanceCount": "$TotalInstanceCount", 
     "WorkflowName": 1 
    } 
    } 
] 

Moje dokumenty zbiórki są następujące:

{ 
     "_id" : ObjectId("550ff07ce4b09bf056df4ac1"), 
     "OutputData" : "xyz", 
     "InputData" : null, 
     "Location" : null, 
     "ChannelName" : "XYZ", 
     "UserId" : 5, 
     "TaskId" : 95, 
     "ChannelId" : 5, 
     "Status" : "Success", 
     "TaskTypeId" : 7, 
     "WorkflowId" : 37, 
     "Task" : "XYZ", 
     "WorkflowStartTime" : ISODate("2015-03-23T05:09:26Z"), 
     "EndTime" : ISODate("2015-03-23T05:22:44Z"), 
     "StartTime" : ISODate("2015-03-23T05:22:44Z"), 
     "TaskType" : "TRIGGER", 
     "WorkflowInstanceId" : "23-3-2015-95d17f17-2580-4fe3-b627-12e862af08ce", 
     "StackTrace" : null, 
     "WorkflowName" : "XYZ data workflow" 
} 

Mam indeksu {WorkflowStartTime: 1, userid: 1, StartTime: 1}

Ich jest prawie 900000 rekordów w kolekcji, a ponieważ korzystam z podzbioru danych, przy kwarantannie z użyciem zakresu dat zajmuje to od 1,5 do 1,7 sekundy. Użyłem struktury agregacji z innymi kolekcjami z ogromnymi danymi, a wydajność jest bardzo dobra. Nie wiem, co jest nie tak z tym zapytaniem, ponieważ pokazuje bardzo powolne wyjście, oczekuję, że będzie ono w młynach jako zapytanie analizy w czasie rzeczywistym. Każdy wskaźnik na nim doceniany.

Wyjście gdy {wyjaśnić: true} dodany do agregacji zapytaniu

{ 
    "stages": [ 


     { 
      "$cursor": { 
      "query": { 
       "UserId": { 
       "$in": [ 
        5 
       ] 
       }, 
       "WorkflowStartTime": { 
       "$gte": "ISODate(2015-04-09T00:00:00Z)", 
       "$lte": "ISODate(2015-04-16T00:00:00Z)" 
       } 
      }, 
      "fields": { 
       "EndTime": 1, 
       "StartTime": 1, 
       "Task": 1, 
       "TaskId": 1, 
       "WorkflowInstanceId": 1, 
       "WorkflowName": 1, 
       "_id": 0 
      }, 
      "plan": { 
       "cursor": "BtreeCursor ", 
       "isMultiKey": false, 
       "scanAndOrder": false, 
       "indexBounds": { 
       "WorkflowStartTime": [ 
        [ 
        "ISODate(2015-04-16T00:00:00Z)", 
        "ISODate(2015-04-09T00:00:00Z)" 
        ] 
       ], 
       "UserId": [ 
        [ 
        5, 
        5 
        ] 
       ] 
       }, 
       "allPlans": [ 
       { 
        "cursor": "BtreeCursor ", 
        "isMultiKey": false, 
        "scanAndOrder": false, 
        "indexBounds": { 
        "WorkflowStartTime": [ 
         [ 
         "ISODate(2015-04-16T00:00:00Z)", 
         "ISODate(2015-04-09T00:00:00Z)" 
         ] 
        ], 
        "UserId": [ 
         [ 
         5, 
         5 
         ] 
        ] 
        } 
       } 
       ] 
      } 
      } 
     }, 
     { 
      "$group": { 
      "_id": { 
       "Task": "$TaskId", 
       "WorkflowId": "$WorkflowInstanceId" 
      }, 
      "TaskName": { 
       "$first": "$Task" 
      }, 
      "StartTime": { 
       "$first": "$StartTime" 
      }, 
      "EndTime": { 
       "$last": "$EndTime" 
      }, 
      "LastExecutionTime": { 
       "$last": "$StartTime" 
      }, 
      "WorkflowName": { 
       "$first": "$WorkflowName" 
      } 
      } 
     }, 
     { 
      "$project": { 
      "_id": true, 
      "LastExecutionTime": true, 
      "TaskName": true, 
      "AverageExecutionTime": { 
       "$subtract": [ 
       "$EndTime", 
       "$StartTime" 
       ] 
      }, 
      "WorkflowName": true 
      } 
     }, 
     { 
      "$group": { 
      "_id": "$_id.Task", 
      "LastExecutionTime": { 
       "$last": "$LastExecutionTime" 
      }, 
      "AverageExecutionTime": { 
       "$avg": "$AverageExecutionTime" 
      }, 
      "TaskName": { 
       "$first": "$TaskName" 
      }, 
      "TotalInstanceCount": { 
       "$sum": { 
       "$const": 1 
       } 
      }, 
      "WorkflowName": { 
       "$first": "$WorkflowName" 
      } 
      } 
     }, 
     { 
      "$project": { 
      "_id": false, 
      "Id": "$_id", 
      "Name": "$TaskName", 
      "LastExecutionDate": { 
       "$substr": [ 
       "$LastExecutionTime", 
       { 
        "$const": 0 
       }, 
       { 
        "$const": 30 
       } 
       ] 
      }, 
      "AverageExecutionTimeInMilliSeconds": "$AverageExecutionTime", 
      "TotalInstanceCount": "$TotalInstanceCount", 
      "WorkflowName": true 
      } 
     } 
     ], 
     "ok": 1 
    } 
+0

[co ma wyjście wyjaśnić powiedzenia o zapytaniu] (http://docs.mongodb.org/manual/reference/command/aggregate/)? – Philipp

+1

@Philipp wyjaś niajĘ ... wynik dodany, zawsze pokazujĘ ... mi to tylko w wyjś ciu wyjaś niajĘ ... cym, ale w dokumentach jest czymś innym, czego mi brakuje? – Ninad

+0

Mówi, że używa 'BtreeCursor', to powinno być w porządku: * Zapytanie używające indeksu ma kursor typu BtreeCursor * (http://openmymind.net/Speedig-Up-Queries-Understanding-Query-Plans /). Czy możesz wykonać zapytanie bez frameworka agregacji i powiedzieć nam, ile znalezionych dokumentów pasujących? '...' może to mogłoby również pomóc w odwróceniu indeksu do '{UserId: 1, WorkflowStartTime: 1}', ponieważ zapytanie '$ match' ma najpierw' UserId', a następnie 'WorkflowStartTime'. Ale może również nie przynieść żadnych korzyści. –

Odpowiedz

2

agregacji nie używać żadnych Index. Trzeba utworzyć nowy indeks:

{UserId:1,WorkflowStartTime:1} 

Jeśli wszystko jest dobre, agrégation + wyjaśnić musi pojawić się następujący wiersz:

"winningPlan" :... 
+0

moje zapytanie już używa indeksu w fazie dopasowywania, a użycie workflowstartTime przed userId w indeksie jest pomocne bcz robimy zapytanie o zakres w WorkflowStartTime – Ninad

+0

Kolejne rozwiązanie, które można zmienić kolejność "dopasowywania", najpierw "WorkflowStartTime" i drugie "Identyfikator użytkownika". Uważam, że indeks nie jest używany w agregacji. –

+2

W wyniku wyjaśniania jej wyświetlanie, wartość dla ** kursora ** w sekcji ** planu ** wynosi ** Btree **, co wskazuje, że indeks jest używany – Ninad