Almoust我的所有文档都包含2个字段,开始时间戳和完成时间戳。在每个我的查询中,我需要获取在选定时间段内的元素。所以start应该在选定的值之后,final应该在选择的时间戳之前。
查询看起来像
db.collection.find({start:{$gt:DateTime(...)}, final:{$lt:DateTime(...)}})
那么该场景的最佳索引策略是什么?
顺便说一下,哪个性能更好 - 将日期存储为日期时间或unix时间戳,这是长值本身
答案 0 :(得分:15)
为 baloo 的答案添加更多内容。
关于时间戳与长期问题。通常,MongoDB服务器不会看到差异。 BSON编码长度相同(64位)。根据驱动程序的编码,您可能会在客户端看到不同的性能。例如,在Java端使用10gen驱动程序时,时间戳呈现为Date
,比Long
重得多。有drivers试图避免这种开销。
另一个问题是,如果关闭索引的第一个字段的范围,您将看到性能改进。因此,如果您使用 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 - Rob。
答案 1 :(得分:2)
您可以使用Compound index为多个字段创建索引。
db.collection.ensureIndex({start: 1, final: 1})
使用explain()比较不同的查询和索引,以充分利用数据库