我正在回答自己的问题,希望它能帮助其他人。我使用的是mongodb(3.4),在一个由10米文档组成的集合中,对一个索引字符串字段运行count()
。我正在寻找非空字符串。以下是一些性能指标,其中slow==collection_scan和fast==index_scan:
+----------------+-----------+
| Constraint |Performance|
+----------------+-----------+
| $exists(false) | slow |
| $exists(true) | slow |
| $ne: '' | slow |
| $eq: '' | fast |
| $eq: null | slow |
+----------------+-----------+
我想我基本上了解发生了什么,即:
1.$存在(false)
不存在的字段将不会进入索引,因此mongodb必须执行集合扫描,以便为count()
收集所有文档。
2.$存在(true)
这就是抓住我的。我以为会很快,但我错了。我认为这是因为如果一个字段存在,并且它的值设置为undefined
,那么$exists()将返回true。我只能假设设置为undefined的字段也不会进入索引,因此mongodb必须再次执行集合扫描,以便为count()收集所有文档。
3.$ne:''
我想这和$exists(false)是一样的
4.$eq:''
这是一个真正的字符串值,因此它必须存在于索引中,因此速度很快。
4.$eq:null
这是另一个吸引我的文档。此文档帮助了很多(https://jira.mongodb.org/browse/SERVER-18653)。简而言之,2.6版本(https://docs.mongodb.com/manual/release-notes/2.6-compatibility/#null-比较查询):
null相等查询(即字段:null)现在匹配具有未定义值的字段
此查询速度较慢。我只能假设未定义的字段没有索引,并且由于null与两者都匹配,因此mongodb必须再次执行集合扫描,以便为count()收集所有文档。
那么,该怎么办呢?
解决方案
最后,我使用正则表达式/^.+$/
查找非空字符串。这使用了索引并且速度极快。同样重要的是,我现在尽量避免使用$exists()
和$ne:
。
感谢