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

sil*_*der 13 indexing mongodb nosql

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

查询看起来像

db.collection.find({start:{$gt:DateTime(...)}, final:{$lt:DateTime(...)}})
Run Code Online (Sandbox Code Playgroud)

那么这种情况的最佳索引策略是什么?


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

Rob*_*ore 16

baloo的回答再加一点.

关于时间戳与长期问题.通常,MongoDB服务器不会看到差异.BSON编码长度相同(64位).根据驱动程序的编码,您可能会在客户端看到不同的性能.例如,在Java端使用10gen驱动程序时,会显示一个时间戳,因为Date它比它重得多Long.有些驱动程序试图避免这种开销.

另一个问题是,如果关闭索引的第一个字段的范围,您将看到性能改进.所以如果你使用baloo建议的索引:

db.collection.ensureIndex({start: 1, final: 1})
Run Code Online (Sandbox Code Playgroud)

如果您查询的话,您的查询将执行(可能更多):

db.collection.find({start:{$gt:DateTime(...),$lt:DateTime(...)}, 
                    final:{$lt:DateTime(...)}})
Run Code Online (Sandbox Code Playgroud)

从概念上讲,如果将索引视为树,则闭合范围限制树的两侧而不是仅限于一侧.如果没有封闭的范围内,服务器必须"检查"的所有条目具有start比提供的,因为它不知道之间的关系的时间戳更大的startfinal.

您甚至可能会发现使用单个字段索引查询性能并不是更好:

db.collection.ensureIndex({start: 1})
Run Code Online (Sandbox Code Playgroud)

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

HTH - Rob.


bal*_*loo 1

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

db.collection.ensureIndex({start: 1, final: 1})
Run Code Online (Sandbox Code Playgroud)

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