2016-05-05 17 views
5

私は多数のドキュメント(32 809 900)を持つコレクションを持っています。すべての文書にsoft_deletedというフィールドがあります。私もsoft_deleted: 1フィールドを作成しました。次に、フィールドに関連するいくつかの異なるクエリをテストしました。ここに私の結果があります:インデックス付きフィールドのMongoDBクエリが非常に遅い

Query        Number of results Time in milliseconds 
db.cgm_egvs 
    .find().count()     32809900   90 
db.cgm_egvs 
    .find({soft_deleted: true})  2820897   688 
    .count() 
db.cgm_egvs 
    .find({soft_deleted: false})  29989003   3983 
    .count() 
db.cgm_egvs 
    .find({soft_deleted: null})  0     42 
    .count() 
db.cgm_egvs 
    .find({soft_deleted: {$ne: true}}) 29989003   82397 
    .count() 

なぜこれらのクエリ間でクエリ時間が異なるのですか?私はsoft_deletedtrueまたはfalseである文書を同じ時間がかかると予想します。 さらに重要なことは、!= trueでのクエリが他のクエリよりもずっと遅いのはなぜですか?

+1

あなたは**追加することができます。各クエリの広告ポスト結果の最後に**(「executionStats」)を説明します。これにより、より詳細な実行の詳細が得られます。 – profesor79

+0

真と偽の違いは、インデックスの選択性によって説明できます。例えば、あなたのドキュメントの10%がsoft_deleted:trueの場合、インデックスはsoft_deleted:trueにマッチするのに便利です。一方、soft_deleted:falseを検索する場合、インデックスはまったく役に立たない。 – joao

答えて

3

soft_deletedフィールドには、非常に低いカーディナリティを持っています;。。真と偽という2つの異なる値しか持たないので、このフィールドにインデックスを持たせることはあまり有益ではありません。通常、カーディナリティの高いフィールドでは、インデックスの方が優れています。

{soft_deleted:true}クエリの場合、soft_deleted:trueの行の数は{soft_deleted:false}と比較して非常に少なく、mongodbはインデックスエントリの数を大幅に減らす必要がありました。したがって、{soft_deleted:true}クエリの実行時間が短縮されました。

同様クエリ{soft_deleted:ヌル}は、インデックスが2つだけ異なる値を有しており、この場合には、はるかに低い走査が必要とされるより少ない時間を要しました。

(選択性は、インデックスを使用して結果を絞り込むために、クエリの能力である)最終的なクエリは、$ NE演算子を使用している、と$ NE演算子は、選択的ではありません。 https://docs.mongodb.com/v3.0/faq/indexes/#using-ne-and-nin-in-a-query-is-slow-why。 したがって、実行にはもっと時間がかかりました。

0

他のクエリがなぜ遅いのかわかりません(私は説明ダンプを待っています)、 ですが、$ neの場合、そこに余分なステップが追加されているということです。つまり、この関数は最初にequalでラップされています。 。その後、等しくない - >parsedQueryセクションで、以下のダンプを説明し、ないはステップ

db.getCollection(A1 '')を見つける見つける参照({レベル:{$ NE: "情報"}}) .explain()

"queryPlanner" : { 
    "plannerVersion" : 1, 
    "namespace" : "logi.a1", 
    "indexFilterSet" : false, 
    "parsedQuery" : { 
     "$not" : { 
      "Level" : { 
       "$eq" : "Info" 
      } 
     } 
    }, 

db.getCollection(A1 '')({レベル: "情報"})を見つける(説明)

"queryPlanner" : { 
    "plannerVersion" : 1, 
    "namespace" : "logi.a1", 
    "indexFilterSet" : false, 
    "parsedQuery" : { 
     "Level" : { 
      "$eq" : "Info" 
     } 
    }, 
関連する問題