2012-10-23 13 views
7

私はこの単純なプレフィックスクエリに悩まされています。あなたは(/^/)プレフィックス正規表現の形式を使用して、かなり良いパフォーマンスを得ることができ、私は結果をソートしようとすると、クエリがかなり遅いですがMongo docs状態:正規表現とソートを使用したMongodbの単純なプレフィックスクエリが遅い

940ミリ

db.posts.find({ハッシュタグ:/^noticias /})。限度(15).sort({ランク:-1})。ヒント( 'hashtags_1_rank_-1')(説明)

{ 
"cursor" : "BtreeCursor hashtags_1_rank_-1 multi", 
"isMultiKey" : true, 
"n" : 15, 
"nscannedObjects" : 142691, 
"nscanned" : 142692, 
"nscannedObjectsAllPlans" : 142691, 
"nscannedAllPlans" : 142692, 
"scanAndOrder" : true, 
"indexOnly" : false, 
"nYields" : 1, 
"nChunkSkips" : 0, 
"millis" : 934, 
"indexBounds" : { 
    "hashtags" : [ 
     [ 
      "noticias", 
      "noticiat" 
     ], 
     [ 
      /^noticias/, 
      /^noticias/ 
     ] 
    ], 
    "rank" : [ 
     [ 
      { 
       "$maxElement" : 1 
      }, 
      { 
       "$minElement" : 1 
      } 
     ] 
    ] 
}, 
"server" : "XRTZ048.local:27017" 
} 

しかし、同じクエリの未分類バージョンは超高速です:

0ミリ秒

db.posts.find({ハッシュタグ:/^noticias /})。限度(15).hint( 'hashtags_1_rank_-1')(説明)

:私はソート正規表現とを削除する場合
{ 
"cursor" : "BtreeCursor hashtags_1_rank_-1 multi", 
"isMultiKey" : true, 
"n" : 15, 
"nscannedObjects" : 15, 
"nscanned" : 15, 
"nscannedObjectsAllPlans" : 15, 
"nscannedAllPlans" : 15, 
"scanAndOrder" : false, 
"indexOnly" : false, 
"nYields" : 0, 
"nChunkSkips" : 0, 
"millis" : 0, 
"indexBounds" : { 
    "hashtags" : [ 
     [ 
      "noticias", 
      "noticiat" 
     ], 
     [ 
      /^noticias/, 
      /^noticias/ 
     ] 
    ], 
    "rank" : [ 
     [ 
      { 
       "$maxElement" : 1 
      }, 
      { 
       "$minElement" : 1 
      } 
     ] 
    ] 
}, 
"server" : "XRTZ048.local:27017" 

}

クエリも速いです

0ミリ秒

db.posts.find({ハッシュタグ: 'noticias'})。限度(15).sort({ランク:-1})。ヒント( 'hashtags_1_rank_-1')。 ()

{ 
"cursor" : "BtreeCursor hashtags_1_rank_-1", 
"isMultiKey" : true, 
"n" : 15, 
"nscannedObjects" : 15, 
"nscanned" : 15, 
"nscannedObjectsAllPlans" : 15, 
"nscannedAllPlans" : 15, 
"scanAndOrder" : false, 
"indexOnly" : false, 
"nYields" : 0, 
"nChunkSkips" : 0, 
"millis" : 0, 
"indexBounds" : { 
    "hashtags" : [ 
     [ 
      "noticias", 
      "noticias" 
     ] 
    ], 
    "rank" : [ 
     [ 
      { 
       "$maxElement" : 1 
      }, 
      { 
       "$minElement" : 1 
      } 
     ] 
    ] 
}, 
"server" : "XRTZ048.local:27017" 

}

これは、正規表現の両方を使用してのように思えるし、ソートモンゴはたくさんのレコードをスキャンします説明。しかし、私は正規表現を使用しない場合、並べ替えはわずか15スキャンです。ここで何が間違っていますか?

+1

jaime、私は '' scanAndOrder''が遅さの原因であると信じています。 [Andreの答え](http://stackoverflow.com/questions/11871187/removing-scanandorder-true-in-my-mongodb-query-result)を見たいかもしれませんが、あなたとまったく同じでない場合も同様かもしれません問題。 – slee

答えて

6

Explain出力でscanAndOrder: trueは、クエリが文書を取得し、出力が返される前に、メモリ内にそれらを並べ替えるために持っていることを示しています。これは高価な操作であり、クエリのパフォーマンスに影響を与えます。

nscannedとの相違点と同様に、scanAndOrder: trueの存在は、問合せが最適な索引を使用していないことを示します。この場合、コレクションスキャンを行う必要があるようです。 sort基準にインデックスキーを含めることで、この問題を軽減することができます。私のテストから:

db.posts.find({hashtags: /^noticias/ }).limit(15).sort({hashtags:1, rank : -1}).explain() 

は、スキャンや順序を必要とし、あなたが探しているレコード数のnnscannedを返しません。これはまた、hashtagsキーの並べ替えを意味しますが、それはあなたにとって有益かもしれませんが、クエリのパフォーマンスを上げるはずです。

+0

ありがとう、それは本当にトリックでした。また、複数を追加している場合には、最初の正規表現からインデックス境界が推定されます。たとえば、次のクエリ: 'db.posts.find({" $ and ":{ハッシュタグ:/^manana /}、{hashtags:/^noticias/}]}).sort({'hashtags ' 1、 'rank': - 1})。limit(10).explain() ' にはマナナのインデックス境界があります。私の場合、アルファベット順で正規表現のクエリを並べ替えると、より良いパフォーマンスが得られました – Darius

関連する問題