我正在寻找有关在MongoDb 3.4中使用哪种索引策略的建议。
假设我们有一个 people 文档集合,其形式如下:
{
_id: 10,
name: "Bob",
age: 32,
profession: "Hacker"
}
让我们假设有一个用于查询集合的web api,并且唯一可能的过滤器是 name 或 age 。
对api的示例调用类似于:http://myAwesomeWebSite/people?name="Bob"&age=25
此类通话将在以下查询中翻译:{{1}}。
为了更好地阐明我们的场景,请考虑:
尽管如此,我们必须决定以下哪个索引提供最佳性能:
db.people.find({name: "Bob", age: 25})
{name: 1, age: 1}
和{name: 1}
根据一些简单的测试,似乎单一复合指数比两个单场指数更高效。
通过mongo shell执行单个查询,explain()方法建议使用单个复合索引,您可以比使用两个单字段索引快10倍地查询数据库。
在更现实的情况下,这种差异似乎不那么剧烈,而不是通过mongo shell执行单个查询,而是对nodejs web应用程序的两个不同URL进行多次调用。两个URL都对数据库执行查询,并将获取的数据作为json数组返回,一个使用具有单个复合索引的集合,另一个使用具有两个单字段索引的集合(两个集合具有完全相同的文档)。登记/> 在这个测试中,单一复合指数似乎仍然是性能方面的最佳选择,但这次差异不太明显。
根据测试结果,我们正在考虑使用单一复合指数方法。
有没有人有关于这个主题的经验?我们是否缺少任何重要的考虑因素(可能是大型复合指数的一些缺点)?
答案 0 :(得分:24)
给定一个简单的标准查询(没有limit()
或sort()
或任何花哨的应用),在两个字段上都有过滤条件(如name
和age
中所示你的例子),为了找到结果文件,MongoDB将:
age
上的索引 - >每次查找仍然会产生无数的文档。name
而不是age
因为与age
相比,很多人会有name
(选择性低)(选择性更高)。但是,该选择还取决于您的具体方案以及您打算针对数据库运行的查询。网上有一篇非常好的文章,关于如何最好地定义考虑到您特定情况的各个方面的复合索引:https://emptysqua.re/blog/optimizing-mongodb-compound-indexes 需要考虑的其他方面是:索引更新以特定价格出现。但是,如果您只关心原始读取速度并且每次只进行一些更新,那么您应该选择更多/更大的索引。
最后但并非最不重要的(!)过度使用的底线建议:使用真实数据甚至是真实的负载情景来描述你的系统。并随着数据/系统的变化而不断进行测量。
补充读物: https://docs.mongodb.com/manual/core/query-optimization/index.html
Index intersection vs. compound index?
mongodb compund index vs. index intersect
How does the order of compound indexes matter in MongoDB performance-wise?