在创建简单的MongoDB查询时,我对查询中的条件排序有疑问 - 例如(Mongoose.js语法):
conditions = { archived: false, first_name: "Billy" };
VS
conditions = { first_name: "Billy", archived: false };
..在一个简单的find()函数中:
User.find(conditions, function(err, users) { <some logic> });
..假设一个简单的单键索引策略:
UserSchema.index( { first_name: 1, archived: 1} );
..上面列出的条件的顺序是否重要?
重要提示:我知道复合索引的顺序很重要,但是上面我对单键索引查询感到好奇。也对完全非索引查询的情况感兴趣,因为我们在这里。 :)
替代解释:换句话说,假设有两个可能的内部MongoDB搜索策略,假设有100 User
个(50个存档,50个没有):
archived
用户,然后搜索其余50个未归档的用户,其first_name
值为“Billy”User
文档中搜索first_name
值“Billy”,然后通过删除已归档的任何Billy来过滤找到的对象。 ..我认为#1更快(在具有两个以上条件的大型查询中可能更快)。但无论哪个更快,为什么,肯定其中一个是。
核心问题:在复杂索引的庞大而强大的世界之外,MongoDB是否知道如何自动执行其最高性能/快速搜索/过滤器,无论哪个字段和哪个排序?或者我们是否需要以编程方式告诉系统什么是最好的(通过所提供条件的顺序等)?
答案 0 :(得分:11)
我对您的问题感到有点困惑,因为您提供的索引({ first_name: 1, archived: 1 }
)是复合索引。以下所有查询都将使用该复合索引:
conditions = { archived: false, first_name: "Billy" };
conditions = { first_name: "Billy", archived: false };
conditions = { first_name: "Billy" };
现在,我们假设我们有两个单独的索引,{ first_name: 1 }
和{ archived: 1 }
。在这种情况下,MongoDB将进行查询优化以确定哪个索引的使用效率最高。 You can read more about the query optimization performed by MongoDB here.
因此,MongoDB查询优化器可能会对您提供的两个多路查询使用相同的索引:
conditions = { archived: false, first_name: "Billy" };
conditions = { first_name: "Billy", archived: false };
或者,您可以使用hint
强制MongoDB使用您选择的索引。一般来说,这可能不是一个好主意。您还可以手动检查哪个索引对特定查询as detailed here最有效。
您可以使用Mongo shell中的.explain()
功能查看查询使用的索引。 (如果没有使用索引,你会在结果文档中看到"cursor" : "BasicCursor"
。另一方面,如果使用复合索引,你会看到像"cursor" : "BtreeCursor first_name_1_archived_1"
这样的东西。如果其中一个使用了单字段索引,您可能会看到"cursor" : "BtreeCursor archived_1"
。
此外,MongoDB的搜索策略如下:
查询优化器并行运行所有可能的查询计划并选择“最佳”查询计划,但所有查询计划都遵循上述策略。 (BasicCursor是一个退化的案例:它遍历所有文档并将谓词应用于每个文档。)
tl; dr?匹配器非常智能,可以在按任意顺序显示时匹配等式谓词。
这有意义吗?