16

ほとんどすべてのドキュメントに、開始タイムスタンプと終了タイムスタンプの 2 つのフィールドが含まれています。そして、各クエリで、選択した期間の要素を取得する必要があります。そのため、開始は選択した値の後、最終は選択したタイムスタンプの前にする必要があります。

クエリは次のようになります

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

では、そのシナリオに最適なインデックス作成戦略は何でしょうか?


ちなみに、どちらがパフォーマンスに優れていますか-日付をdatetimesまたはunixタイムスタンプとして保存することは、長い値そのものです

4

2 に答える 2

17

balooの回答にもう少し追加します。

タイムスタンプと長い問題について。通常、MongoDB サーバーは違いを認識しません。BSON エンコード長は同じ (64 ビット) です。ドライバーのエンコーディングに応じて、クライアント側で異なるパフォーマンスが表示される場合があります。例として、Java 側で 10gen ドライバーを使用すると、タイムスタンプがレンダリングされDateますLong。そのオーバーヘッドを回避しようとするドライバーがあります。

もう 1 つの問題は、インデックスの最初のフィールドの範囲を閉じると、パフォーマンスが向上することです。したがって、balooによって提案されたインデックスを使用する場合:

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

クエリが次の場合、クエリのパフォーマンスが (潜在的にはるかに) 向上します。

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

概念的には、インデックスをツリーと考えると、閉じた範囲はツリーの片側だけではなく両側を制限します。start閉じた範囲がないと、サーバーはと の関係がわからないため、提供されたタイムスタンプより大きいすべてのエントリを「チェック」する必要がありstartますfinal

次のような単一のフィールド インデックスを使用しても、クエリのパフォーマンスが向上しないことがあります。

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

節約のほとんどは、最初のフィールドの剪定によるものです。これが当てはまらないのは、クエリがインデックスによってカバーされている場合、または結果の順序付け/並べ替えがインデックスから派生できる場合です。

HTH - ロブ。

于 2013-03-24T19:37:00.883 に答える
2

複数のフィールドのインデックスを作成するために、複合インデックスを使用できます。

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

Explain()を使用してさまざまなクエリとインデックスを比較し、データベースを最大限に活用します

于 2013-03-24T17:56:20.767 に答える