1

次のスキーマを持つドキュメントを含むレッスンのコレクションがあります

{
    title: "Programming 101",
    category: 1
    likes: 10,
    author: {
        name: "Mike",
        reputation: 100,
        rating: 1500
    },
    created: 154895126, // unix timestamp
    content: ".... html ... "
}

私のアプリケーションのインデックス ページでは、すべてのカテゴリから最新の 18 のレッスンを表示するので、これは

db.lessons.find().sort({created:-1}).limit(18)

これは非常に一般的なクエリであり、レッスン コレクションはシステム内で最大のコレクションになるため、可能な限り最適化したいので、created にインデックスを作成しました。

db.lessons.ensureIndex({created:-1})

でも、あるカテゴリーのレッスンだけ受けたいときもある

db.lessons.find({category:1}).sort({created:-1}).limit(18)

そのため、カテゴリにもインデックスを追加しました。そうしないと、mongo は簡単に並べ替えることができますが、カテゴリ = 1 のものを取得するために要素ごとにチェックする必要があるためです。

db.lessons.ensureIndex({category:1})

カテゴリで並べ替えないので、昇順で 1 を渡します。

さて、問題は、いいね、著者の評判、および著者の評価でレッスンを並べ替えたいことです。これらは非常に一般的なタスクであり、作成された並べ替えほど一般的ではありませんが、それでも非常に一般的です。さらに3つのインデックスを追加する必要がありますか? それとも作成したものを使用しますか?

db.lessons.ensureIndex({likes:-1})
db.lessons.ensureIndex({'author.reputation':-1})
db.lessons.ensureIndex({'author.rating':-1})

あまりにも多くのインデックスを使用している可能性があり、メモリ内のコレクション サイズが巨大になる可能性があります。

4

2 に答える 2

4

asya の集計インデックスの動きに 3 番目に同意します。

> db.lessons.ensureIndex({category:1});
> db.lessons.ensureIndex({created:-1});
> db.lessons.find({category:1}).sort({created:-1}).limit(18).explain();
{
    "cursor" : "BtreeCursor category_1",
    "nscanned" : 1,
    "nscannedObjects" : 1,
    "n" : 1,
    "scanAndOrder" : true,
    "millis" : 0,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
        "category" : [
            [
                1,
                1
            ]
        ]
    }
}

ここで Explain() は、MongoDB が、SQL データベースで期待される方法で両方の個々のインデックスを使用しないことを示しています。

> db.lessons.ensureIndex({category:1,created:-1});
> db.lessons.find({category:1}).sort({created:-1}).limit(18).explain();
{
    "cursor" : "BtreeCursor category_1_created_-1",
    "nscanned" : 1,
    "nscannedObjects" : 1,
    "n" : 1,
    "millis" : 0,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
        "category" : [
            [
                1,
                1
            ]
        ],
        "created" : [
            [
                {
                    "$maxElement" : 1
                },
                {
                    "$minElement" : 1
                }
            ]
        ]
    }
}

総合指数は確かに勝者のようです。

インデックスが多すぎるという懸念については、私の日常の仕事で、 --notablescan オプションを使用してテーブル スキャンを無効にした 3,800 万を超えるドキュメントを含むコレクションを扱っています。クエリごとに調整されたインデックスを持つことが不可欠であることがわかりました。

于 2012-11-23T19:59:49.427 に答える
0

あなたがそれを言及した場合

これらは非常に一般的なタスクになります

私の意見では、インデックスを使用する必要があります。そうしないと、結果が得られる前にクエリがコレクション内のすべてのドキュメントを通過するためです。もちろん、より正確に答えるには、コレクションの数と、もちろん「共通のもの」に関するいくつかのメトリックを知っている必要があります。そして、どのように振る舞うべきかを決定する最善の方法は、いくつかのテストを実行することです。

ユーザーが一定期間(2 日間)にどのように行動したかを収集し、各タイプのクエリが何回表示されたかを確認します。あなたは今、それぞれの「共通性」になります。インデックスの有無にかかわらず、これらのタイプのクエリをシミュレートして、何がうまく機能するかを確認してください。

また、ここでの返信に関して@Asyaに同意します

2 番目のインデックスが {category:1, created:-1} でない理由はありますか

于 2012-11-22T21:06:01.143 に答える