我几乎所有的文档都包含 2 个字段,开始时间戳和结束时间戳。在我的每个查询中,我都需要获取选定时间段内的元素。所以开始应该在选定的值之后,最终应该在选定的时间戳之前。
查询看起来像
db.collection.find({start:{$gt:DateTime(...)}, final:{$lt:DateTime(...)}})
那么对于这种情况最好的索引策略是什么?
顺便说一句,这对性能更好 - 将日期存储为日期时间或 unix 时间戳,这本身就是长值
也为baloo的答案添加了更多内容。
关于时间戳与长问题。通常 MongoDB 服务器不会看到差异。BSON 编码长度相同(64 位)。根据驱动程序的编码,您可能会在客户端看到不同的性能。例如,在 Java 端 a 使用 10gen 驱动程序渲染时间戳,因为Date
它比Long
. 有些驱动程序试图避免这种开销。
另一个问题是,如果您关闭索引第一个字段的范围,您将看到性能改进。因此,如果您使用baloo建议的索引:
db.collection.ensureIndex({start: 1, final: 1})
如果您查询的是:
db.collection.find({start:{$gt:DateTime(...),$lt:DateTime(...)},
final:{$lt:DateTime(...)}})
从概念上讲,如果您将索引视为一棵树,则封闭范围会限制树的两侧,而不仅仅是一侧。如果没有封闭范围,服务器必须“检查”所有start
大于提供的时间戳的条目,因为它不知道 和 之间的start
关系final
。
您甚至可能会发现使用单个字段索引的查询性能并没有更好,例如:
db.collection.ensureIndex({start: 1})
大部分节省来自第一个字段的修剪。不会出现这种情况的情况是查询被索引覆盖,或者结果的排序/排序可以从索引中得出。
HTH - 抢。