创建可确保选择性的查询
选择性是查询使用索引缩小结果范围的能力。有效索引更具选择性,并允许 MongoDB 将索引用于与实现查询相关的大部分工作。
为确保选择性,请编写带有索引字段的查询,以限制可能的文档数量。编写相对于索引数据具有适当选择性的查询。
Example
假设您有一个名为status
的字段,其中可能的值为new
和processed
。如果在status
上添加索引,则创建了低选择性索引。该索引对查找记录几乎没有帮助。
根据您的查询,一种更好的策略是创建一个compound index,其中包含低选择性字段和另一个字段。例如,您可以在status
和created_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 使用。