创建可确保选择性的查询

选择性是查询使用索引缩小结果范围的能力。有效索引更具选择性,并允许 MongoDB 将索引用于与实现查询相关的大部分工作。

为确保选择性,请编写带有索引字段的查询,以限制可能的文档数量。编写相对于索引数据具有适当选择性的查询。

Example

假设您有一个名为status的字段,其中可能的值为newprocessed。如果在status上添加索引,则创建了低选择性索引。该索引对查找记录几乎没有帮助。

根据您的查询,一种更好的策略是创建一个compound index,其中包含低选择性字段和另一个字段。例如,您可以在statuscreated_at.上创建复合索引

再次取决于您的用例的另一种选择可能是使用单独的集合,每种状态一个。

Example

考虑一个集合上的索引{ a : 1 }(即键a上的索引以升序排列),其中a具有三个值,该值在整个集合中均匀分布:

{ _id: ObjectId(), a: 1, b: "ab" }
{ _id: ObjectId(), a: 1, b: "cd" }
{ _id: ObjectId(), a: 1, b: "ef" }
{ _id: ObjectId(), a: 2, b: "jk" }
{ _id: ObjectId(), a: 2, b: "lm" }
{ _id: ObjectId(), a: 2, b: "no" }
{ _id: ObjectId(), a: 3, b: "pq" }
{ _id: ObjectId(), a: 3, b: "rs" }
{ _id: ObjectId(), a: 3, b: "tv" }

如果您查询{ a: 2, b: "no" },则 MongoDB 必须扫描集合中的 3 documents以返回一个匹配的结果。同样,对{ a: { $gt: 1}, b: "tv" }的查询必须扫描 6 个文档,并且还返回一个结果。

考虑一个集合上的相同索引,其中a具有* n **个值在整个集合中均匀分布:

{ _id: ObjectId(), a: 1, b: "ab" }
{ _id: ObjectId(), a: 2, b: "cd" }
{ _id: ObjectId(), a: 3, b: "ef" }
{ _id: ObjectId(), a: 4, b: "jk" }
{ _id: ObjectId(), a: 5, b: "lm" }
{ _id: ObjectId(), a: 6, b: "no" }
{ _id: ObjectId(), a: 7, b: "pq" }
{ _id: ObjectId(), a: 8, b: "rs" }
{ _id: ObjectId(), a: 9, b: "tv" }

如果您查询{ a: 2, b: "cd" },则 MongoDB 必须仅扫描一个文档即可完成查询。索引和查询更具选择性,因为a的值均匀分布并且查询可以使用索引选择特定的文档。

但是,尽管a上的索引更具选择性,但诸如{ a: { $gt: 5 }, b: "tv" }之类的查询仍需要扫描 4 个文档。

如果总体选择性低,并且 MongoDB 必须读取许多文档以返回结果,则某些查询在没有索引的情况下可能会执行得更快。要确定性能,请参见度量 Metrics 使用