2011-10-23 13 views
3

私が追跡しなければならない私の文書のさまざまなタイムスタンプを索引付けするためのより効率的な技術であると思うものは、私のアプリケーションはかなり重いですが、索引なしで読むことはかなり重いです。 。MongoDB多くのインデックス対サブドキュメントの配列上の単一インデックス?

各タイムスタンプにフィールドを持ち、各フィールドにインデックスを付けるか、タイムスタンプとその関連タイプを配列フィールドに格納し、その配列の各フィールドにインデックスを付ける方がよいでしょうか?

最初のオプション、別々のフィールド、およびそれぞれのインデックス:

{ 
    "_id" : "...", 
    "Field1.Timestamp" : '2011-01-01 01:00.000', 
    "Field2.Timestamp" : '2011-01-01 01:00.000', 
    "Field3.Timestamp" : '2011-01-01 01:00.000', 
    "Field4.Timestamp" : '2011-01-01 01:00.000', 
    "Field5.Timestamp" : '2011-01-01 01:00.000', 
    "Field6.Timestamp" : '2011-01-01 01:00.000', 
    "Field7.Timestamp" : '2011-01-01 01:00.000', 
    "Field8.Timestamp" : '2011-01-01 01:00.000', 
    "Field9.Timestamp" : '2011-01-01 01:00.000', 
} 

db.mycollection.ensureIndex({ "Field1.Timestamp" : 1 }); 
db.mycollection.ensureIndex({ "Field2.Timestamp" : 1 }); 
db.mycollection.ensureIndex({ "Field3.Timestamp" : 1 }); 
db.mycollection.ensureIndex({ "Field4.Timestamp" : 1 }); 
db.mycollection.ensureIndex({ "Field5.Timestamp" : 1 }); 
db.mycollection.ensureIndex({ "Field6.Timestamp" : 1 }); 
db.mycollection.ensureIndex({ "Field7.Timestamp" : 1 }); 
db.mycollection.ensureIndex({ "Field8.Timestamp" : 1 }); 
db.mycollection.ensureIndex({ "Field9.Timestamp" : 1 }); 

そして、タイムスタンプの配列とそのステータスがあります、ただ一つの指標と

{ 
    "_id" : "...", 
    "Timestamps" : [ 
     { "Type" : "Field1", "Timestamp" : '2011-01-01 01:00.000' }, 
     { "Type" : "Field2", "Timestamp" : '2011-01-01 01:00.000' }, 
     { "Type" : "Field3", "Timestamp" : '2011-01-01 01:00.000' }, 
     { "Type" : "Field4", "Timestamp" : '2011-01-01 01:00.000' }, 
     { "Type" : "Field5", "Timestamp" : '2011-01-01 01:00.000' }, 
     { "Type" : "Field6", "Timestamp" : '2011-01-01 01:00.000' }, 
     { "Type" : "Field7", "Timestamp" : '2011-01-01 01:00.000' }, 
     { "Type" : "Field8", "Timestamp" : '2011-01-01 01:00.000' }, 
     { "Type" : "Field9", "Timestamp" : '2011-01-01 01:00.000' }, 
    ] 
} 

db.mycollection.ensureIndex({ "Timestamps.Type" : 1, "Timestamps.Timestamp" : 1 }); 

は私が道オフアムここの印?

+0

あなたのクエリはどのように見えますか? –

+0

クエリは$ LT比較のタイムスタンプフィールドを使用します。{"Field1Timetamp":{$ LT: "2011-01-01 01:00.000"}、 "BatchExpires":{$ LT: "2011-01-01 01: 00.000 "}、" Prioritized ":true} インデックスには他の2つのフィールドも含まれますが、わかりやすくするために、いくつかのフィールドがないため、それらを残しました(BatchExpiresとPrioritizedフィールド) – Redth

+0

私の考えは、配列内のフィールドに9または10のインデックスよりも効率的なサブ文書の配列の2つのインデックスです... – Redth

答えて

2

これは基本的に、サイズNのインデックス10が1つのインデックスN * 10よりも効率的である場合に沸騰します。純粋に読み取りを参照すると、別々のインデックスは常により高速になります。関連するB-treeは歩く小さなキーセットなどを検討する

しかし、考慮すべきポイントがいくつかあります:配列フィールド上

  • インデックス基本的にインデックス別々に各配列要素は。そのため、ルックアップのオーバーヘッドはbツリーウォーク中に最大でも1〜2の追加ステップであり、これは無視できるパフォーマンスです。言い換えれば、彼らはほぼ同じくらい速くなるでしょう。
  • インデックスが10個の場合、各更新/挿入にインデックスを複数回更新する必要があります(インデックスが1つのフィールドを共有するか、1回に複数のタイムスタンプを更新するかによって異なります)。これは重要なパフォーマンスの考慮事項です。
  • 配列インデックスを使用すると、タイムスタンプ(タイムスタンプ10など)を追加するのが少し簡単になります。
  • データベース(24k)ごとに使用できる名前空間の数には制限があり、各インデックスは1つをとります。フィールドごとに別々のインデックスを作成すると、これが問題になる可能性があります。
  • 最も重要なのは、配列インデックスがより簡単でコードが単純化され、保守性が向上することです。パフォーマンスの違いが限られていることを考えれば、ここでアレイインデックスの動機付けが強くなると言えます。
+0

それで、あなたはUPDATE/INSERTのために、1つのインデックスを持つことが、別々のインデックスよりもずっと速くなければならないことを示唆していますか?索引付けされるオブジェクトの配列であれば、索引を更新するオーバーヘッドが増えるかどうかはわかりませんでした。索引付けが必要な20個のフィールド以上は実際にはないはずですが、 ... – Redth

+0

代替手段が2つ以上のインデックスを更新する必要がある場合は、より高速です。配列インデックスは、他のインデックスとは扱いが異なりません。配列内のすべての値は別々に索引付けされます。 –

関連する問題