“文档” 菜单
文档首页
/
MongoDB Manual
/ /

创建索引以确保查询选择性

在此页面上

  • 举例

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

为确保选择性,编写查询时应限制索引字段或字段可能包含的文档数量。根据索引数据编写具有适当选择性的查询。

请考虑具有以下形式的文档的集合:

{
status: "processed",
product_type: "electronics"
}

在此示例中,集合中99 % 的文档的 statusprocessed 。 如果您在status上添加索引并查询statusprocessed的文档,则索引对此查询的选择性较低。 但是,如果要查询具有processedstatus的文档,此索引具有很高的选择性,因为查询仅读取索引的1 %。

考虑一个文档集合,其中 status 字段有三个值分布在集合中:

[
{ _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 上添加索引并查询 { "status": "pending", "product_type": "electronics" },MongoDB 必须读取三个索引键才能返回一个匹配的结果。同样,对 { "status": { $in: ["processed", "pending"] }, "product_type" : "electronics" } 的查询必须读取六个文档才能返回两个匹配的文档。

考虑集合上的同一索引,其中 status 拥有 9 个在集合中分布的值:

[
{ _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 相等性的查询更具选择性,但像 { "status": { $gt: 5 }, "product_type": "grocery" } 这样的查询仍然需要读取四个文档。但是,如果在 product_typestatus 上创建一个复合索引,对 { "status": { $gt: 5 }, "product_type": "grocery" } 的查询只需读取两个文档。

为了提高选择性,您可以创建复合索引,以缩小查询读取的文档范围。例如,如果要提高statusproduct_type查询的选择性,可以对这两个字段创建复合索引。

如果 MongoDB 要读取大量文档才能返回结果,那么某些查询在没有索引的情况下可能会执行得更快。要确定性能,请参阅测量索引使用情况

← 确保索引容纳在 RAM

在此页面上