3

現在、準大規模な更新に使用している OR クエリがあります。基本的に、私のコレクションは 2 つのデータ セットに分割されます。

1 つのメイン リポジトリとメイン リポジトリの 1 つのサブセット。これは、データの小さなサブセットをすばやく検索できるようにするためです。

しかし、サブセットにプルするために作成したクエリがタイムアウトしていることがわかりました..説明を見ると、実際には2つのクエリが発生しているように見えます.

PRIMARY> var date = new Date(2012,05,01);
PRIMARY> db.col.find(
  {"$or":[
      {"date":{"$gt":date}},
      {"keywords":{"$in":["Help","Support"]}}
   ]}).explain();

これにより、次が生成されます。

{
"clauses" : [
    {
        "cursor" : "BtreeCursor ldate_-1",
        "nscanned" : 1493872,
        "nscannedObjects" : 1493872,
        "n" : 1493872,
        "millis" : 1035194,
        "nYields" : 3396,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
            "ldate" : [
                [
                    ISODate("292278995-01--2147483647T07:12:56.808Z"),
                    ISODate("2012-06-01T07:00:00Z")
                ]
            ]
        }
    },
    {
        "cursor" : "BtreeCursor keywords_1 multi",
        "nscanned" : 88526,
        "nscannedObjects" : 88526,
        "n" : 2515,
        "millis" : 1071902,
        "nYields" : 56,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
            "keywords" : [
                [
                    "Help",
                    "Help"
                ],
                [
                    "Support",
                    "Support"
                ]
            ]
        }
    }
],
 "nscanned" : 1582398,
 "nscannedObjects" : 1582398,
 "n" : 1496387,
 "millis" : 1071902
}

これを高速化するために、より良いインデックスを作成できるものはありますか? ゆっくりする方法のようです...

お早めにどうぞ!

4

2 に答える 2

1

$orクエリは各句を個別に評価し、結果を組み合わせて重複を削除します。したがって、クエリを最適化する場合は、最初に各句を個別にexplain()する必要があります。

nYields問題の一部は、高値(3396)で証明されているように、そのコレクションに積極的に書き込んでいる間に多数のドキュメントを取得していることのようです。mongostatクエリの実行中に出力を確認して、ページの障害、%のロック、キューの読み取り/書き込みなどの他の要因を検討することをお勧めします。

多数のドキュメントと非常にアクティブなコレクションの更新に対してこのクエリを高速化したい場合は、次の2つのベストプラクティスアプローチを検討してください。

1)事前集計

基本的に、これはドキュメントが挿入/更新されるときに集計統計を更新するため、高速のリアルタイムクエリを実行できます。MongoDBのマニュアルでは、このユースケースについて詳しく説明しています:事前集計レポート

2)インクリメンタルマップ/リデュース

インクリメンタルMap/Reduceアプローチを使用して、連続するバッチの集計統計を計算できます(たとえば、1時間ごとまたは1日ごとのcronジョブから)。このアプローチでは、reduce出力オプションを使用してMap / Reduceを実行し、結果を新しいコレクションに保存し、queryこのMap/Reduceジョブが最後に実行されてから作成/更新されたドキュメントのみを選択するフィルターを含めます。

于 2012-11-03T13:40:20.367 に答える
0

日付とキーワードの両方に複合インデックスを作成する必要があると思います。ユースケースに基づく詳細については、以下の投稿を参照してください

mongodbで複合インデックスを構成する方法

于 2012-11-02T13:18:31.980 に答える