用于不同字段的范围查询的mongodb索引策略

时间:2013-03-24 17:51:53

标签: mongodb indexing nosql

Almoust我的所有文档都包含2个字段,开始时间戳和完成时间戳。在每个我的查询中,我需要获取在选定时间段内的元素。所以start应该在选定的值之后,final应该在选择的时间戳之前。

查询看起来像

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

那么该场景的最佳索引策略是什么?


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

2 个答案:

答案 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大于提供的时间戳,因为它不知道startfinal之间的关系。

您甚至可能会发现使用单个字段索引(例如:

)的查询性能并不好
db.collection.ensureIndex({start: 1})

大部分节省来自第一场的修剪。不是这种情况的情况是当索引覆盖查询时,或者可以从索引中导出结果的排序/排序。

HTH - Rob。

答案 1 :(得分:2)

您可以使用Compound index为多个字段创建索引。

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

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