我有一个包含大量文件的集合(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_deleted
为true
或false
的文档占用相同的时间。
更重要的是,为什么!= true
查询比任何其他查询慢得多?
答案 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"
}
},