2017-04-13 11 views
0

私はインデックス付きインデックスコレクションtimestamp_1, timestamp_2 and user_idを持っています。クエリを実行すると(次のログに表示されます)、約3分(175670ms)のクエリが実行されます。私はなぜそれが起こっているのか分からない!! 以下のMongoDB-Logを添付しました。
ログに従う人は誰でも説明できますが、どうすれば最適化できますか?MongoDBのログ出力を説明してください

2017-04-12T17:04:33.759 + 0000 I COMMAND [conn167]クエリ 位置コレクションクエリ:{ORDERBY:{timestamp_1:1}、$クエリ:{ $と:[{timestamp_1。 {$のLTE:1492016294486.0}}、{timestamp_2:{ $ GTE:1491993563400.0}}、{USER_ID: "jkfjlsjfflki-14asddsd"}]}} planSummary:IXSCAN {USER_ID:1}、IXSCAN {USER_ID:1} ntoreturn :1000 ntoskip:0 keysExamined:27254 docsExamined:27254 hasSortStage:1 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numHields:3350 nreturned:67 reslen:176574ロック:{グローバル:{ acquireCount:{r:6702}}、データベース:{acquireCount:{r: 3351}}、 コレクション:{acquireCount:{R:3351}}} 175670ms

もう一つ質問:私は "_id" フィールド任意の欠点この方法の私自身の価値を作成しています?私は単なる文字列値を作成しており、mongoDbが何の問題もなくインデックスを作成することを期待しています。

2017-04-12T17:04:41.979 + 0000 I [conn150]クエリdb.users クエリコマンド:{ORDERBY:{_id:1}、$クエリ:{_id: 「USR-dfhsddf- 14905426shfkjdhf」}} planSummary:iDHACK ntoreturn:1 ntoskip:0 keysExamined:1 docsExamined:1 idhack:1 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:0 nreturned:1 reslen:1291の ロック:{グローバル:{acquireCount :{R:2}}、データベース:{acquireCount: {R:1}}、コレクション:{acquireCount:{R:1}}} 2627ms

ありがとうございました!

答えて

0

最初に2番目の質問に答える - _idに独自の値を使用しても問題ありません。 MongoDBは適切にインデックスを作成します。これを行う結果、重複していないことを確認するのがアプリケーションの責任となります。

デフォルトのMonogDB ObjectIdタイプには、値にタイムスタンプも含まれています。これは、ObjectIdであるときに_idフィールドによる順序付けが、挿入順(またはObjectIdが作成された注文時の技術的タイムスタンプ)で結果を返すことを意味します。

ログ出力に関しては、クエリパフォーマンスの出力値は、データベースプロファイラからのものです。値のリストはhttps://docs.mongodb.com/manual/reference/database-profiler/にあります。

クエリのパフォーマンスに非常に役立つツールは、explain(),https://docs.mongodb.com/manual/reference/method/cursor.explain/およびhttps://docs.mongodb.com/manual/reference/explain-results/です。クエリの実行方法を自分のシステムでテストする必要があります。

個々のフィールドのコレクションには、timestamp_1,timestamp_2user_idという3つの異なるインデックスがあるようです。

あなたはまたによって発注された値を

  • timestamp_1
  • timestamp_2が値
  • user_idよりも大きい値より小さい等しい:

    クエリは、次の3つのフィールドを比較しています出力のtimestamp_1フィールド。

    planSummary: IXSCAN { user_id: 1 }, IXSCAN { user_id: 1 }は問い合わせプランナが再びされていない、並べ替えに使用するuser_idのインデックスを選択すると、クエリのuser_idにインデックスを選択していることを述べているあなたが実際にソートするフィールド。参考までにhttps://groups.google.com/forum/#!topic/mongodb-user/nQlmVdODo-Mを参照してください。

    keysExamined:27254は、インデックススキャンがインデックス内の27254個のキーを調べたことを意味します。 docsExamined:27254は、MongoDBが27245文書をディスクから取り出して内容を調べることを意味します。 nreturned:67は、クエリの結果が67個のドキュメントを返すと述べています。 user_idインデックスがスキャンされ、27254個の一致が見つかると、各ドキュメントがコレクションから取得されます。これらの文書は解析され、timestamp*フィールドが比較され、67個の一致するレコードが返されます。 timestamp_1およびtimestamp_2のインデックスは使用されません。

    MongoDBは索引をB-TREEとして格納し、複合索引(https://docs.mongodb.com/manual/indexes/)を許可します。新しい索引の組み合わせをテストし、結果をプロファイルし、アプリケーションに最適なものを確認することができます。 3つのフィールドをすべて含む複合インデックスを使用すると、インデックスのみを使用してすべてのクエリフィールド(user_idtimestamp_1、およびtimestamp_2)をクエリで分析できるため、MongoDBがディスクから読み込む必要があるドキュメントの数を減らすことができます。一つの可能​​性のある例は次のとおりです。

    db.collection.createIndex({user_id:1, timestamp_1:1, timestamp_2:-1) 
    

    このインデックスは、モンゴの問い合わせプランナがtimestamp_2がその値よりも大きい場合、それ以上の結果を見つけ、その後、timestamp_1が値未満の結果を見つけ、その後、user_idフィールドを一致させることができます。 timestamp_1timestamp_2の前にリストされているので、一致するレコードはすでにソートされているため、MongoDBはソートフェーズをスキップできます。パフォーマンスを向上させるためには、自分のシステムでこれをテストする必要があります。コレクション内のドキュメントのカーディナリティに応じて、timestampフィールドをuser_idフィールドの前に置くことができます。

関連する問題