集合事件包含userId和一系列事件 - 数组中的每个元素都是嵌入式文档。例如:mongodb - 不使用日期索引
{
"_id" : ObjectId("4f8f48cf5f0d23945a4068ca"),
"events" : [
{
"eventType" : "profile-updated",
"eventId" : "247266",
"eventDate" : ISODate("1938-04-27T23:05:51.451Z"),
},
{
"eventType" : "login",
"eventId" : "64531",
"eventDate" : ISODate("1948-05-15T23:11:37.413Z"),
}
],
"userId" : "junit-19568842",
}
使用如下面在过去30天内产生的一个事件找到相当的查询:
db.events.find({ events : { $elemMatch: { "eventId" : 201,
"eventDate" : {$gt : new Date(1231657163876) } } } } ).explain()
查询计划显示的“events.eventDate”索引时使用测试数据包含较少的事件(大约20个):
{
"cursor" : "BtreeCursor events.eventDate_1",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"events.eventDate" : [
[
ISODate("2009-01-11T06:59:23.876Z"),
ISODate("292278995-01--2147483647T07:12:56.808Z")
]
]
}
}
然而,当有大量的事件(约500),不使用索引:
{
"cursor" : "BasicCursor",
"nscanned" : 4,
"nscannedObjects" : 4,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
为什么当有很多事件没有被使用的索引?可能在 有大量事件时,MongoDB发现只扫描所有项目比使用索引更有效率?
你在抱怨说,优化器不会在需要0ms返回的查询上使用索引吗? :) – 2012-04-19 02:49:59
上面的解释输出来自测试集合。大约20M的文件,查询大约需要8秒。 – dsatish 2012-04-19 14:15:11
如果您查询集合文档的重要部分,则这样的范围查询可能会很慢。您可以使用提示来强制索引来比较速度,但我认为它会做索引扫描一样慢。您应该在生产数据中发布解释,不论有无提示。问题是,如果你找到了几百万条匹配的文件,那么检查它们需要一些时间。 – 2012-04-19 14:34:04