我创建了一个复合索引:MongoDB的为什么是一个复合指数包括2dsphere不使用
db.lightningStrikes.createIndex({ datetime: -1, location: "2dsphere" })
但是当我运行MongoDB的下面的查询不考虑指数,使得COLLSCAN。
db.lightningStrikes.find({ datetime: { $gte: new Date('2017-10-15T00:00:00Z') } }).explain(true).executionStats
完整的结果是波纹管:
{
"executionSuccess" : true,
"nReturned" : 2,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 4,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"datetime" : {
"$gte" : ISODate("2017-10-115T00:00:00Z")
}
},
"nReturned" : 2,
"executionTimeMillisEstimate" : 0,
"works" : 6,
"advanced" : 2,
"needTime" : 3,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 4
},
"allPlansExecution" : [ ]
}
诗篇。我只插入了4个文档。
为什么会发生?
https://gist.github.com/anonymous/8dc084132016a1dfe0efb150201f04c7
db.lightningStrikes.find({ datetime: { $gte: new Date('2017-10-11T23:59:56Z'), $lte: new Date('2017-10-11T23:59:57Z') } }).hint("datetime_-1_location_2dsphere").explain(true)
从上面的查询结果:从上面的查询
db.lightningStrikes.find({ datetime: { $gte: new Date('2017-10-11T23:59:56Z'), $lte: new Date('2017-10-11T23:59:57Z') } }).explain(true)
结果 https://gist.github.com/anonymous/2b76c5a7b4b348ea7206d8b544c7d455
这个数据库只是一个示例,我创建它,因为在生产中我具有相同的结构,它发生的行为相同,但具有数十亿个文档。 当我通过datetime和另一个字段创建复合索引时,但datetime与geospatial不起作用。有点奇怪! 我已经尝试了“提示”,但尽管MongoDB考虑了索引,但实际上它扫描内存中的所有索引,而不是按日期间隔过滤。 我检查了文档,它应该工作。 https://docs.mongodb.com/manual/core/2dsphere/#create-a-compound-index-with-2dsphere-index-key – Michael
我不认为这是这个问题的一般答案,即没有'使用我的索引'在MongoDB中切换:)。所以,任何试图为这个问题提供具体答案的人都需要看比较解释计划。我强烈建议使用[docs](https://docs.mongodb.com/manual/tutorial/analyze-query-plan/)帮助收集这两个计划并自行审查它们以帮助理解解释输出的内容告诉你。 – glytching
我觉得它很奇怪它通过日期时间和另一种类型的字段与复合索引一起使用,并且不适用于日期时间和地理空间字段。无论如何,我会在我的问题上追加“解释”,谁知道帮助确定发生的事情。 – Michael