Ich habe rund 75.000 Dokumente in einer Sammlung.Mongo finden Abfrage dauert 2 Minuten
Die Gesamtgröße der Datenbank beträgt ca. 45 GB.
Von den 75.000 Dokumenten sind etwa 45.000 von jeweils 900 KB (etwa 42 GB) und die restlichen Dokumente etwa 120 KB.
Jedes Dokument ist einer custId
ObjectId in einer anderen Sammlung zugeordnet und hat eine timestamp
, beide indiziert.
Jetzt muss ich die Dokumente für eine bestimmte custId
für letzten Monat abrufen. Die Zählung ist ungefähr 5500 Dokumente. Diese custId
hat die kleinen Dokumente mit einer Größe von jeweils etwa 120 KB.
Im Anschluss an meine Anfrage:
db.mycollection.find(
{
custId:ObjectId("CUST_OBJECT_ID_HERE"),
timestamp:{$gte:one_month_ago_date, $lt:current_date}
}).sort({timestamp:-1})
noch die Abfrage dauert 2 Minuten, um alle Datensätze zu holen. Liegt es an der Anzahl der Dokumente oder an der Größe der größeren Dokumente? Gibt es eine Möglichkeit, das zu beheben?
HINWEIS: Es dauert 2 Minuten, wenn die Abfrage von Nodejs ausgelöst wird. Wenn ich es auf Mongo Shell feuere, kommt es schnell zurück, aber es könnte sein, weil es nur die ersten 50 Datensätze holt. Als ich .count()
an die Abfrage der Mongo-Shell anschloss, dauerte es 2 Minuten, um mit der Zählung zurückzukehren.
Update:
Indexing Details:
"wiredTiger" : {
"nindexes" : 3,
"totalIndexSize" : 2396160,
"indexSizes" : {
"_id_" : 1138688,
"custId_1" : 598016,
"timestamp_1" : 659456
}
}
Output Erklären: (mit Art)
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "mydb.mycollection",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"custId" : {
"$eq" : ObjectId("CUST_OBJECT_ID_HERE")
}
},
{
"timestamp" : {
"$lt" : ISODate("2017-05-15T14:20:04.393Z")
}
},
{
"timestamp" : {
"$gte" : ISODate("2017-04-15T14:20:04.393Z")
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"custId" : {
"$eq" : ObjectId("CUST_OBJECT_ID_HERE")
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"timestamp" : 1
},
"indexName" : "timestamp_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "backward",
"indexBounds" : {
"timestamp" : [
"(new Date(1494858004393), new Date(1492266004393)]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "SORT",
"sortPattern" : {
"timestamp" : -1
},
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"timestamp" : {
"$lt" : ISODate("2017-05-15T14:20:04.393Z")
}
},
{
"timestamp" : {
"$gte" : ISODate("2017-04-15T14:20:04.393Z")
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"custId" : 1
},
"indexName" : "custId_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"custId" : [
"[ObjectId('CUST_OBJECT_ID_HERE'), ObjectId('CUST_OBJECT_ID_HERE')]"
]
}
}
}
}
}
]
},
"serverInfo" : {
"host" : "test-machine",
"port" : 27017,
"version" : "3.2.12",
"gitVersion" : "REMOVED_BY_OP"
},
"ok" : 1
}
ist es wegen der Sorte. Es muss das Ganze entweder in den Speicher oder auf die Festplatte laden. Wegen der Größe der Datenbank wird es wahrscheinlich auf die Festplatte geladen, die langsam ist. Sie könnten versuchen, nur die Eigenschaften anzugeben, die Sie abrufen müssen, wodurch es leichter wird und es möglicherweise in den Speicher passt. Ich denke, es wird auch nur 1 Index verwenden, wenn die Sortierung verwendet wird, und es wird den Timestamp-Index auswählen und den custId-Index ignorieren. Sie könnten versuchen, einen zusammengesetzten Index für custId und timestamp hinzuzufügen. – PeteG
Verwenden Sie auch Paginierung, wenn Sie nicht alle Dokumente benötigen –
Welche Indizes haben Sie für diese Sammlung? hast du versucht mongodb zu erklären? Wie funktioniert diese Abfrage ohne Sortierung innerhalb der Mongo Shell? – Astro