【发布时间】:2016-08-22 20:29:29
【问题描述】:
以下是我的数据库中的一个简化版本的文档:
{
_id : 1,
main_data : 100,
sub_docs: [
{
_id : a,
data : 22
},
{
_id: b,
data : 859
},
{
_id: c,
data: 151
},
... snip ...
{
_id: m,
data: 721
},
{
_id: n,
data: 111
}
]
}
所以想象一下,我有一百万个具有不同数据值(例如 0 - 1000)的此类文档。目前我的查询是这样的:
db.myDb.find(
{ sub_docs: { $elemMatch: { data: { $gte: 110, $lt: 160 } } } }
)
另外说上面的查询只会匹配大约 0.001% 的数据(因此总共返回大约 10 个文档)。
我有一个索引集使用:
db.myDb.ensureIndex( sub_docs.data )
对此数据执行定时测试似乎表明在 sub_docs.data 上没有设置任何索引的情况下它更快。
我正在使用 Mongo 3.2.8。
编辑 - 附加信息:
我的定时测试是一个 Perl 脚本,它查询服务器然后拉回相关数据。当我启用索引时,我首先运行了这个测试,但是缓慢的查询时间迫使我做一些挖掘工作。我想看看如果我删除索引,查询时间会有多糟糕,但是它改善了查询的响应时间! 我走得更远了,我绘制了查询响应时间与数据库中文档总数的关系,两个图都显示查询时间线性增加,但查询索引以更快的速度增加. 在进行测试的过程中,我一直在关注服务器内存使用情况(很低),因为我的第一个想法是索引不适合内存。
所以总的来说,我的问题是:为什么对于这个特定的查询,这个查询在没有索引的情况下表现更好? 有没有办法用更好的索引来提高这个查询的速度?
更新
好的,已经有一段时间了,我已将其范围缩小到不限制查询搜索参数两侧的索引。
上面的查询将显示一个索引范围:
[-inf, 160]
而不是 110 到 160。 我可以通过使用 index min 和 max 函数来解决这个问题,如下所示:
db.myDb.find(
{ sub_docs: { $elemMatch: { data: { $gte: 110, $lt: 160 } } } }
).min({'subdocs.data': 110}).max({'subdocs.data': 160})
但是(如果可能的话)我更喜欢不同的方式来做这件事,因为我想使用聚合函数(它似乎不支持最小/最大索引函数)
【问题讨论】:
-
@JohnnyHK 我在上面添加了一些额外的信息,你是绝对正确的,现在有一个实际的问题要回答:-)
-
谢谢,查看
explain的查询输出并将其添加到您的问题中。
标签: mongodb mongodb-query mongodb-indexes