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

时间:2016-05-05 12:48:47

标签: 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()

为什么这些查询之间的查询时间如此不同?我希望找到soft_deletedtruefalse的文档占用相同的时间。 更重要的是,为什么!= true查询比任何其他查询慢得多?

2 个答案:

答案 0 :(得分: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。 所以执行需要花费更多的时间。

答案 1 :(得分:0)

我不确定为什么其他查询很慢(因为我正在等待解释转储), 但是,如果$ ne,关键是我们在那里添加了额外的步骤,这意味着这个函数被包装在第一个相等然后不相等 - >请参阅 parsedQuery 部分中的解释转储,找到步骤

  。

db.getCollection( 'A1')找到({级别:{$ NE: “信息”}})。解释()

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

db.getCollection( 'A1')找到({等级: “信息”})。解释()

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