Ich habe eine MongoDB-Sammlung namens post
mit 35 Millionen Objekte. Die Sammlung hat zwei Sekundärindizes, die wie folgt definiert sind.Langsame Bereichsabfrage auf einem Multi-Kachel-Index
> db.post.getIndexKeys()
[
{
"_id" : 1
},
{
"namespace" : 1,
"domain" : 1,
"post_id" : 1
},
{
"namespace" : 1,
"post_time" : 1,
"tags" : 1 // this is an array field
}
]
Ich erwarte, dass die folgende Abfrage, die einfach filtert durch namespace
und post_time
, in einer angemessenen Zeit laufen, ohne dass alle Objekte zu scannen.
>db.post.find({post_time: {"$gte" : ISODate("2013-04-09T00:00:00Z"), "$lt" : ISODate("2013-04-09T01:00:00Z")}, namespace: "my_namespace"}).count()
7408
Allerdings dauert es MongoDB mindestens zehn Minuten das Ergebnis und neugierig abzurufen, sie verwaltet 70 Millionen Objekte scannen den Job nach der explain
Funktion zu tun.
> db.post.find({post_time: {"$gte" : ISODate("2013-04-09T00:00:00Z"), "$lt" : ISODate("2013-04-09T01:00:00Z")}, namespace: "my_namespace"}).explain()
{
"cursor" : "BtreeCursor namespace_1_post_time_1_tags_1",
"isMultiKey" : true,
"n" : 7408,
"nscannedObjects" : 69999186,
"nscanned" : 69999186,
"nscannedObjectsAllPlans" : 69999186,
"nscannedAllPlans" : 69999186,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 378967,
"nChunkSkips" : 0,
"millis" : 290048,
"indexBounds" : {
"namespace" : [
[
"my_namespace",
"my_namespace"
]
],
"post_time" : [
[
ISODate("2013-04-09T00:00:00Z"),
ISODate("292278995-01--2147483647T07:12:56.808Z")
]
],
"tags" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "localhost:27017"
}
Der Unterschied zwischen der Anzahl der Objekte und der Anzahl der Scans müssen von den Längen der Markierungsarrays hervorgerufen werden (die alle gleich 2 sind). Trotzdem verstehe ich nicht, warum post_time
Filter den Index nicht nutzt.
Können Sie mir sagen, was ich fehlen könnte?
(Ich arbeite an einer Abfahrt Maschine mit 24 Kernen und 96 GB RAM Ich bin mit MongoDB 2.2.3.).
Hat Namespace eine sehr geringe Mächtigkeit bekam? – Sammaye
Momentan gibt es nur einen eindeutigen 'Namespace'-Wert, den ich verwende. –
Ja, deshalb, MongoDB auf dem ersten Feld zuerst beschränken müssen, so dass es alle 'my_namespace' bekommt und dann erhält alle Dokumente zwischen diesem Datum, etc etc, versuchen, den Index-Neuordnungs so die post_time erste ist – Sammaye