创建索引以确保查询选择性
本页内容
选择性是查询通过索引缩小结果的能力。有效的查询更具选择性,并允许 MongoDB 在满足查询相关工作的更大部分中使用索引。
为确保选择性,编写限制具有索引字段或字段的可能文档数量的查询。编写相对于您的索引数据具有适当选择性的查询。
示例
具有许多常见值的可选择性
考虑一个具有以下形式的文档集合
{ status: "processed", product_type: "electronics" }
在这个例子中,状态
字段中,集合中有99%的文档状态为已处理
。如果您在状态
上添加索引并查询状态为已处理
的文档,该索引对此查询的可选择性较低。但是,如果您想要查询没有状态
为已处理
的文档,则此索引具有很高的可选择性,因为查询只读取了索引的1%。
分布式值的可选择性
考虑一个文档集合,其中状态
字段有三个值,分布在集合中
[ { _id: ObjectId(), status: "processed", product_type: "electronics" }, { _id: ObjectId(), status: "processed", product_type: "grocery" }, { _id: ObjectId(), status: "processed", product_type: "household" }, { _id: ObjectId(), status: "pending", product_type: "electronics" }, { _id: ObjectId(), status: "pending", product_type: "grocery" }, { _id: ObjectId(), status: "pending", product_type: "household" }, { _id: ObjectId(), status: "new", product_type: "electronics" }, { _id: ObjectId(), status: "new", product_type: "grocery" }, { _id: ObjectId(), status: "new", product_type: "household" } ]
如果您在状态
上添加索引并查询{ "status": "pending", "product_type": "electronics" }
,MongoDB必须读取三个索引键以返回一个匹配的结果。同样,查询{ "status": { $in: ["processed", "pending"] }, "product_type" : "electronics" }
必须读取六个文档以返回两个匹配的文档。
考虑集合中同一索引,其中状态
有九个值分布在集合中
[ { _id: ObjectId(), status: 1, product_type: "electronics" }, { _id: ObjectId(), status: 2, product_type: "grocery" }, { _id: ObjectId(), status: 3, product_type: "household"}, { _id: ObjectId(), status: 4, product_type: "electronics" }, { _id: ObjectId(), status: 5, product_type: "grocery"}, { _id: ObjectId(), status: 6, product_type: "household"}, { _id: ObjectId(), status: 7, product_type: "electronics" }, { _id: ObjectId(), status: 8, product_type: "grocery" }, { _id: ObjectId(), status: 9, product_type: "household" } ]
如果您查询{ "status": 2, "product_type": "grocery" }
,MongoDB只读取一个文档来满足查询。索引和查询更具有选择性,因为只有一个匹配的文档,并且查询可以使用索引选择该特定文档。
尽管本例中在状态
上的查询对等性更具有选择性,但如{ "status": { $gt: 5 }, "product_type": "grocery" }
之类的查询仍然需要读取四个文档。然而,如果您在product_type
和状态
上创建一个复合索引,那么对于{ "status": { $gt: 5 }, "product_type": "grocery" }
的查询只需要读取两个文档。
为了提高选择性,您可以创建一个复合索引,以缩小查询读取的文档。例如,如果您想提高对状态
和product_type
查询的选择性,您可以在这些两个字段上创建一个复合索引。
如果MongoDB读取大量文档以返回结果,则某些查询在没有索引的情况下可能执行得更快。要确定性能,请参阅测量索引使用情况。