Mongo查询 - 约束数量与速度(以及索引!)

4
假设我在数据库中有一百万个条目,其中每个条目有十个字段(“列”)。在我看来,我搜索的列越多,查询速度就越快 - 例如:
db.items.find( { 
    $and: [ 
        { field1: x }, 
        { field2: y },
        { field3: z}
    ] 
} )

比以下更快:

db.items.find( { 
    $and: [ 
        { field1: x }, 
        { field2: y }
    ] 
} )

虽然我很想说“太好了,我完全明白了”——但事实并非如此。我只知道它发生在我的特定情况中,并且想知道这是否总是正确的。如果是这样的话,理想情况下,我想知道为什么。
此外,在创建多字段索引时,按任何顺序排列是否有帮助。例如,假设我添加了一个复合索引
db.collection.ensureIndex( { field1: 1, field2: 1, field3: 1 } )

这些有任何排序吗?如果有,顺序会有影响吗?假设90%的项目将符合field1标准,但1%的项目将符合field3标准。对它们进行排序是否会产生某种差异?
2个回答

3

可能情况是更严格的查询返回的文档较少,因为有 90% 的项目将匹配 field1 的条件,只有 1% 的项目将匹配 field3 的条件。查看 explain 对于两个查询的解释。

Mongo 有相当好的 profiler。试一试。尝试不同的索引和不同的查询。当然不要在生产数据库上进行操作。

索引中字段的顺序很重要。如果您有一个索引 { field1: 1, field2: 1, field3: 1 }
和一个查询 db.items.find( { field2: x, field3: y }),索引将完全不被使用,
对于查询 db.items.find( { field1: x, field3: y }) 它仅能部分使用 field1

从另一方面来说,在查询中,条件的顺序并不重要:
db.items.find( { field1: x, field2: y })db.items.find( { field2: y, field1: x }) 一样好,并且两种情况下都会使用索引。
选择索引策略时,您应该检查数据和典型查询。可能的情况是,索引交集 对您更有效,而且与单个复合索引相比,简单索引(如 { field1: 1}, { field2: 1}, { field3: 1})可以获得更好的总体性能,而不是为不同类型的查询创建多个复合索引。
还要检查索引大小以适应内存。在大多数情况下都是这样。

1

这有点复杂... MongoDB会将最近访问的文档保存在内存中,并且查询计划是在第一次执行查询时计算的,因此第二次运行查询可能比第一次快得多。

但是,撇开这些不谈,复合索引的顺序确实很重要。在复合索引中,您可以按照创建索引的顺序使用索引,有点像打开一扇门,穿过去后发现还有更多的门要打开。

因此,设置两个重叠的索引,例如:

{ city: 1, building: 1, room: 1 }

AND

{ city: 1, building: 1 }

这将是一种浪费,因为您仍然可以使用"{city: 1, building: 1, room: 1}"索引的前两个级别(字段)搜索特定建筑物中的所有房间。

您的直觉确实有道理。如果您必须在建筑物中找到一个特定的房间,直接进入正确的城市,直接进入正确的建筑物,然后知道建筑物中大致的位置将比不知道大致位置更快地找到房间(假设有很多房间)。查看B-Tree中的级别,例如这里的搜索可视化效果:http://visualgo.net/bst.html

然而,并非所有数据都整齐地按排序顺序分布 - 例如,英文姓名或单词倾向于在共同字母下聚集在一起 - 以字母X开头的单词不多。

(免费,在线的) MongoDB University开发人员课程涵盖了索引的相关内容,但了解查询性能的最佳方法是查看explain()方法针对查询的结果,以查看是否使用了索引,或者是否扫描了集合(COLLSCAN)。

db.items.find( { 
    $and: [ 
        { field1: x }, 
        { field2: y }
    ] 
})
.explain()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接