4

私はmongoDBを使用してクエリログを保存し、それに関する統計を取得しています。私がmongoDBに保存するオブジェクトには、クエリのテキスト、日付、ユーザー、ユーザーが結果をクリックした場合などが含まれます。

今、特定の日にユーザーがクリックしなかったすべてのクエリを Java で取得しようとしています。私のコードはおよそこれです:

    DBObject query = new BasicDBObject();
    BasicDBObject keys = new BasicDBObject();
    keys.put("Query", 1);
    query.put("Date", new BasicDBObject("$gte", beginning.getTime()).append("$lte", end.getTime()));
    query.put("IsClick", false);
    ...
    DBCursor cur = mongoCollection.find(query, keys).batchSize(5000);

クエリの出力には、反復する必要がある約 20,000 レコードが含まれています。問題は、数分かかることです:(。私は正常ではないと思います。サーバーログから私は見ます:

Wed Nov 16 16:28:40 query db.QueryLogRecordImpl ntoreturn:5000 reslen:252403 nscanned:59260 { Date: { $gte: 1283292000000, $lte: 1283378399999 }, IsClick: false }  nreturned:5000 2055ms
Wed Nov 16 16:28:40 getmore db.QueryLogRecordImpl cid:4312057226672898459 ntoreturn:5000 query: { Date: { $gte: 1283292000000, $lte: 1283378399999 }, IsClick: false }  bytes:232421 nreturned:5000 170ms
Wed Nov 16 16:30:27 getmore db.QueryLogRecordImpl cid:4312057226672898459 ntoreturn:5000 query: { Date: { $gte: 1283292000000, $lte: 1283378399999 }, IsClick: false }  bytes:128015 nreturned:2661 --> 106059ms

したがって、最初のチャンクの取得には 2 秒、2 番目のチャンクの取得には 0.1 秒、3 番目のチャンクの取得には 106 秒かかります!!! 奇妙な..バッチサイズを変更し、DateとIsClickにインデックスを作成し、マシンを再起動しようとしました:Pですが、方法はありません。どこが間違っていますか?

4

1 に答える 1

5

ここには、速度に影響を与える要因がいくつかあります。ここで原因を特定するには、追加のデータを収集する必要があります。

いくつかの潜在的な問題:

  1. 索引:正しい索引を使用していますか? おそらく にインデックスを付けているはずIsClick/Dateです。これは、通常の提案である範囲を 2 番目に置きます。これは のインデックス作成とは異なることに注意してくださいDate/IsClick。順序が重要です。.explain()クエリで を試して、使用されているインデックスを確認してください。
  2. データサイズ:場合によっては、データが多すぎるために速度が低下することがあります。これは、ドキュメントが多すぎるか、大きなドキュメントが多すぎる可能性があります。また、非常に大きな干し草の山からあまりにも多くの針を見つけようとすることによっても発生する可能性があります. 252k のデータ ( reslen) と 12k のドキュメントを戻すので、これはおそらく問題ではありません。
  3. ディスク IO: MongoDB はメモリ マップ ファイルを使用するため、大量の仮想メモリを使用します。RAM よりも多くのデータがある場合、特定のドキュメントをフェッチするには「ディスクに移動」する必要があります。ディスクへの移動は、非常にコストのかかる操作になる可能性があります。iostatまたは(Windows)などのツールを使用しresmonてディスク アクティビティを監視することにより、「ディスクへの移動」を特定できます。

個人的な経験に基づいて、#1 から悪化する可能性があるので、#3 を強く疑っています。.explain()クエリの実行中に IO を監視することから始めます。これにより、考えられる問題の範囲をすばやく絞り込むことができます。

于 2011-11-16T17:27:33.307 に答える