2013-03-24 6 views
10

Almoust alle meine Dokumente sind 2 Felder, Start-Zeitstempel und Ziel-Zeitstempel. Und in jeder meiner Fragen muss ich Elemente erhalten, die sich im ausgewählten Zeitraum befinden. Der Start sollte also nach dem ausgewählten Wert erfolgen und das Finale sollte vor dem ausgewählten Zeitstempel liegen.mongodb Index Strategie für Bereichsabfrage mit verschiedenen Feldern

Abfrage sieht aus wie

db.collection.find({start:{$gt:DateTime(...)}, final:{$lt:DateTime(...)}}) 

Also, was die beste Indexstrategie für dieses Szenario?


Durch die Art und Weise, die für die Leistung besser ist - zum Speichern von Datum als Datetimes oder als Unix-Zeitstempel, der sich lange Wert

Antwort

3

Sie können eine Compound index verwenden, um einen Index für mehrere Felder zu erstellen .

db.collection.ensureIndex({start: 1, final: 1}) 

Vergleichen Sie verschiedene Abfragen und Indizes von explain() mit das Beste aus Ihrer Datenbank

+0

Ja, ich weiß über Composit-Index. Das einzige, was ich fürchte, in diesem Fall wird es keine Vorteile für die kombinierte Abfrage über Einzelfeldabfrage sein. Aber ich weiß es nicht genau. Denken Sie, dass einige Experimente benötigt werden. –

+0

Solange das einzelne Feld das erste Feld im zusammengesetzten Index ist, sind Sie gut zu gehen – baloo

11

hinzufügen, ein wenig mehr zu baloo ‚s Antwort zu bekommen.

Auf dem Zeitstempel vs. langes Problem. Im Allgemeinen sieht der MongoDB-Server keinen Unterschied. Die BSON-Codierungslänge ist dieselbe (64 Bits). Abhängig von der Codierung des Treibers wird auf der Clientseite möglicherweise eine andere Leistung angezeigt. Als ein Beispiel, auf der Java-Seite unter Verwendung eines der 10gen Fahrer ein Zeitstempel als Date gemacht wird, das viel schwerer ist als Long ist. Es gibt drivers, die versuchen, diesen Overhead zu vermeiden.

Das andere Problem ist, dass Sie eine Leistungsverbesserung sehen, wenn Sie den Bereich für das erste Feld des Index schließen. Also, wenn Sie den Index von baloo vorgeschlagen verwenden:

db.collection.ensureIndex({start: 1, final: 1}) 

Sie Abfrage durchführen (potentiell viel) besser, wenn Sie die Anfrage:

db.collection.find({start:{$gt:DateTime(...),$lt:DateTime(...)}, 
        final:{$lt:DateTime(...)}}) 

Konzeptionell, wenn Sie der Indizes als aa denken Baum Der geschlossene Bereich begrenzt beide Seiten des Baumes und nicht nur eine Seite. Ohne den geschlossenen Bereich hat der Server zu „überprüfen“ alle Einträge mit einem start größer ist als der Zeitstempel versehen, da sie nicht weiß, von der Beziehung zwischen start und final.

Vielleicht finden Sie sogar, dass die Abfrage-Leistung nicht besser wird, wie ein einzelnes Feld Index mit:

db.collection.ensureIndex({start: 1}) 

Die meisten der Einsparungen aus dem ersten Feld der Beschneidung ist. Der Fall, in dem dies nicht der Fall ist, ist der Fall, wenn die Abfrage durch den Index abgedeckt ist oder das Ordnen/Sortieren für die Ergebnisse aus dem Index abgeleitet werden kann.

HTH - Rob.

+0

Große Notiz über die Obergrenze für das erste Element.Es ist sehr natürlich und könnte die Leistung stark beeinträchtigen. =) Aber immer noch zwischen Einzelfeld und Composite-Index zu zögern. Denken Sie, dass einige Experimente benötigt werden. –

Verwandte Themen