コレクションにフィールド a
, b
, c
があるとして、{ a: 1, b: 1, c: 1 }
と { a: 1 }
, { b: 1 }
, { c: 1 }
というindexがある場合...
> db.c1.getIndexes();
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.c1"
},
{
"v" : 1,
"key" : {
"a" : 1,
"b" : 1,
"c" : 1
},
"name" : "a_1_b_1_c_1",
"ns" : "test.c1"
},
{
"v" : 1,
"key" : {
"a" : 1
},
"name" : "a_1",
"ns" : "test.c1"
},
{
"v" : 1,
"key" : {
"b" : 1
},
"name" : "b_1",
"ns" : "test.c1"
},
{
"v" : 1,
"key" : {
"c" : 1
},
"name" : "c_1",
"ns" : "test.c1"
}
]
いろんなパターンで試してみる
find( { a: 1 } ) した場合
> db.c1.find( { a: 1 } ).explain();
{
"cursor" : "BtreeCursor a_1_b_1_c_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 2,
"nscannedAllPlans" : 2,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 10,
"indexBounds" : {
"a" : [
[
1,
1
]
],
"b" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"c" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "pellinore.local:27017",
"filterSet" : false
}
{ a: 1, b: 1, c: 1 }
が使われました。
あ、{ a: 1 }
じゃなくてそっちなんですね。
find( { b: 1 } ) した場合
> db.c1.find( { b: 1 } ).explain();
{
"cursor" : "BtreeCursor b_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"b" : [
[
1,
1
]
]
},
"server" : "pellinore.local:27017",
"filterSet" : false
}
{ b: 1 }
が使われました。
そんな気がしていました。
find( { a: 1, b: 1 } ) した場合
> db.c1.find( { a: 1, b: 1 } ).explain();
{
"cursor" : "BtreeCursor b_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 3,
"nscannedAllPlans" : 3,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"b" : [
[
1,
1
]
]
},
"server" : "pellinore.local:27017",
"filterSet" : false
}
{ b: 1 }
が使われました。
{ a: 1, b: 1, c: 1 }
を使うのかと思っていました。
find( { b: 1, a: 1 } ) した場合
{ b: 1 }
が使われました。
find( { a: 1, c: 1 } ) した場合
{ c: 1 }
が使われました。
find( { b: 1, c: 1 } ) した場合
{ c: 1 }
が使われました。
ぴったり一致するのがないので{ b: 1 }
か{ c: 1 }
のどちらかなんでしょう。
find( { a: 1, b: 1, c: 1 } ) した場合
{ c: 1 }
が使われました。
な、なぜ!?
find( { a: 1, c: 1, b: 1 } ) した場合
{ c: 1 }
が使われました。
う、うーん、、、
find( { a: 1, b: 1 } ).sort( { c: 1 } ) した場合
{ a: 1, b: 1, c: 1 }
が使われました。
find( { b: 1, c: 1 } ).sort( { a: 1 } ) した場合
{ a: 1, b: 1, c: 1 }
が使われました。
まとめ
-
{ a: 1 }
は一度も使われていないところを見ると、{ a: 1 }
より{ a: 1, b: 1, c: 1 }
のほうが優先されるみたい。 -
{ a: 1, b: 1, c: 1 }
のようにぴったり一致するindexがあっても使ってくれない場合があるみたい。
ちょっとよくわからないので、ドキュメントを読んでから追記予定。