对索引字段的MongoDB查询非常慢

xx7*_*aBs 6 mongodb

我有一个包含大量文件的集合(32 809 900).所有文档都有一个名为的字段soft_deleted.我也创造了soft_deleted: 1田野.然后我测试了一些与该领域相关的不同查询.这是我的结果:

Query                                Number of results  Time in milliseconds
db.cgm_egvs
  .find().count()                    32809900           90
db.cgm_egvs
  .find({soft_deleted: true})        2820897            688
  .count()
db.cgm_egvs
  .find({soft_deleted: false})       29989003           3983
  .count()
db.cgm_egvs
  .find({soft_deleted: null})        0                  42
  .count()
db.cgm_egvs
  .find({soft_deleted: {$ne: true}}) 29989003           82397
  .count()
Run Code Online (Sandbox Code Playgroud)

为什么这些查询之间的查询时间如此不同?我期望查找文档,其中soft_deletedtruefalse采取相同的时间量.更重要的是,为什么查询!= true比任何其他查询慢得多?

小智 4

soft_deleted 字段的基数非常低;它只有两个不同的值 true 和 false,因此在此字段上建立索引不会有太大好处。通常索引在基数高的字段上表现更好。

在 {soft_deleted: true} 查询的情况下,与 {soft_deleted: false} 相比,具有 soft_deleted: true 的行数要少得多,并且 mongodb 必须扫描的索引条目数量要少得多。因此 {soft_deleted: true} 查询花费的时间更少。

类似地,查询 {soft_deleted: null} 花费的时间更少,因为索引只有 2 个不同的值,在这种情况下,需要的扫描量要少得多。

您的最终查询使用 $ne 运算符,并且 $ne 运算符没有选择性(选择性是查询使用索引缩小结果范围的能力)。 https://docs.mongodb.com/v3.0/faq/indexes/#using-ne-and-nin-in-a-query-is-slow-why。因此执行起来花费了更多的时间。