MongoDB索引字段查询非常缓慢

6

我有一个包含大量文档(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()

为什么这些查询的查询时间如此不同?我期望在查找 soft_deletedtruefalse 的文档时花费相同的时间。更重要的是,为什么通过 != true 进行查询比其他任何查询都要慢这么多?


1
你能否在每个查询的末尾添加 .explain("executionStats") 并发布结果。这将允许获取更多的执行细节。 - profesor79
真与假的区别可能是由索引选择性解释的。例如,如果你的文档中有10%的soft_deleted:true,那么索引对于匹配soft_deleted:true是有用的。另一方面,当搜索soft_deleted:false时,索引就有点无用了。 - joao
2个回答

4
soft_deleted字段的基数非常低,它只有两个不同的值:true和false,所以在此字段上建立索引将不会带来太多好处。通常情况下,索引对具有高基数的字段执行更好。
在{soft_deleted: true}查询的情况下,具有soft_deleted: true的行数与{soft_deleted: false}相比非常少,因此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

0

我不确定为什么其他查询很慢(因为我正在等待解释转储), 但是在$ne的情况下,重点是我们添加了额外的步骤, 这意味着该函数首先包含在相等条件中,然后再不相等 -> 请参见下面的parsedQuery部分中的解释转储,并找到not步骤。

db.getCollection('a1').find({Level:{$ne:"Info"}}).explain()

"queryPlanner" : {
    "plannerVersion" : 1,
    "namespace" : "logi.a1",
    "indexFilterSet" : false,
    "parsedQuery" : {
        "$not" : {
            "Level" : {
                "$eq" : "Info"
            }
        }
    },

db.getCollection('a1').find({Level:"Info"}).explain()

"queryPlanner" : {
    "plannerVersion" : 1,
    "namespace" : "logi.a1",
    "indexFilterSet" : false,
    "parsedQuery" : {
        "Level" : {
            "$eq" : "Info"
        }
    },

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接