16

我几乎所有的文档都包含 2 个字段,开始时间戳和结束时间戳。在我的每个查询中,我都需要获取选定时间段内的元素。所以开始应该在选定的值之后,最终应该在选定的时间戳之前。

查询看起来像

db.collection.find({start:{$gt:DateTime(...)}, final:{$lt:DateTime(...)}})

那么对于这种情况最好的索引策略是什么?


顺便说一句,这对性能更好 - 将日期存储为日期时间或 unix 时间戳,这本身就是长值

4

2 回答 2

17

也为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 - 抢。

于 2013-03-24T19:37:00.883 回答
2

您可以使用复合索引来为多个字段创建索引。

db.collection.ensureIndex({start: 1, final: 1})

使用explain()比较不同的查询和索引,以充分利用数据库

于 2013-03-24T17:56:20.767 回答