post
という名前のMongoDBコレクションがあり、というオブジェクトがあります。コレクションには、次のように定義された2つの2次インデックスがあります。マルチキーインデックスのクエリが遅い
> db.post.getIndexKeys()
[
{
"_id" : 1
},
{
"namespace" : 1,
"domain" : 1,
"post_id" : 1
},
{
"namespace" : 1,
"post_time" : 1,
"tags" : 1 // this is an array field
}
]
は、私は単にnamespace
とpost_time
によってフィルタ次のクエリは、すべてのオブジェクトをスキャンすることなく、合理的な時間内で実行することを期待します。
>db.post.find({post_time: {"$gte" : ISODate("2013-04-09T00:00:00Z"), "$lt" : ISODate("2013-04-09T01:00:00Z")}, namespace: "my_namespace"}).count()
7408
はしかし、それは不思議、それはexplain
機能に応じて仕事をする7000万オブジェクトをスキャンするために管理し、その結果を取得するために、MongoDBの少なくとも10分かかります。
> db.post.find({post_time: {"$gte" : ISODate("2013-04-09T00:00:00Z"), "$lt" : ISODate("2013-04-09T01:00:00Z")}, namespace: "my_namespace"}).explain()
{
"cursor" : "BtreeCursor namespace_1_post_time_1_tags_1",
"isMultiKey" : true,
"n" : 7408,
"nscannedObjects" : 69999186,
"nscanned" : 69999186,
"nscannedObjectsAllPlans" : 69999186,
"nscannedAllPlans" : 69999186,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 378967,
"nChunkSkips" : 0,
"millis" : 290048,
"indexBounds" : {
"namespace" : [
[
"my_namespace",
"my_namespace"
]
],
"post_time" : [
[
ISODate("2013-04-09T00:00:00Z"),
ISODate("292278995-01--2147483647T07:12:56.808Z")
]
],
"tags" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "localhost:27017"
}
オブジェクトの数及びスキャンの数との差は、(すべての2に等しい)タグ配列の長さによって引き起こされなければなりません。それでも、私はなぜpost_time
フィルタがインデックスを利用していないのか分かりません。
私に何が欠けているか教えていただけますか?この質問に私の答えを見つけ
(私は24個のコアと96ギガバイトのRAMと下降マシンに取り組んでいます私はMongoDBの2.2.3を使用しています。。)
名前空間のカーディナリティが非常に低くなっていますか? – Sammaye
現在、使用している名前空間の名前空間の名前は1つだけです。 –
それで、MongoDBはまず最初のフィールドを制限しなければならないので、 'my_namespace'をすべて取得してから、その日付の間にすべてのドキュメントを取得します。そうすれば、post_timeが最初になるようにインデックスを並べ替えます。 – Sammaye