MongoDB比搜索“不存在”更快地搜索“null”?

时间:2012-06-06 15:58:35

标签: mongodb nosql

我的理解是查询null查找为null的字段以及不存在的字段。

mongo手册还指出,即使使用索引,“$ exists也不是很有效”

查询null也应该被视为低效吗?

如果您知道要查找的字段存在但是为null,则写入更有效:

db.foo.find({“y”:{$ type:10}})

比:

db.foo.find({“y”:null})

假设该字段已编入索引

编辑:给出一些使用方式的背景,以便人们可以提出更好的方法: 我正在跟踪文档上发生的处理步骤。 我有每个步骤的时间戳,所以我知道它何时发生。 定期执行内务处理流程并检查尚未发生的任何任务(即没有完成时间戳)以确保不会遗漏任何内容

2 个答案:

答案 0 :(得分:2)

我无法肯定地说出哪一个更快,但是thread in the news group其中有人对$type - 查询的效果存在问题。

除此之外,我不会使用$type查询有三个原因:

  1. 它更难阅读和理解。即使是普通的MongoDB用户也可能不知道{type : 10}是不是最重要的。
  2. 正如您已经指出的那样,语义是不同的。 $type查询允许两种不同类型的空值,即字段不存在的文档,以及字段存在但为空的文档。在反序列化时,这可能会在大多数语言中变成相同的对象,但$type - 查询将区分它们。
  3. 索引用于索引数据,而不是元信息。即使查询优化器能够映射它,我仍然坚持更直接的解决方案。
  4. 我认为另一个性能风险可能是空值的潜在低选择性:如果一半文档具有某个值y并且一半文档具有空y,则查询空值 - 元素将返回大量文档,迭代游标可能会很昂贵。只有在存在大量空值时才会这样。

答案 1 :(得分:1)

我在这里做了一个快速测试并运行了几个解释来查看每个查询的样子,首先是指定类型的那个:

PRIMARY> db.nulltest.find( { "a" : { $type : 10 } } ).explain()
{
    "cursor" : "BtreeCursor a_1",
    "nscanned" : 110011,
    "nscannedObjects" : 110011,
    "n" : 110011,
    "millis" : 121,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
        "a" : [
            [
                null,
                null
            ]
        ]
    }
}

然后是以null作为标准的那个:

PRIMARY> db.nulltest.find( { "a" : null  } ).explain()
{
    "cursor" : "BtreeCursor a_1",
    "nscanned" : 110011,
    "nscannedObjects" : 110011,
    "n" : 110011,
    "millis" : 122,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
        "a" : [
            [
                null,
                null
            ]
        ]
    }
}

结果看起来非常相同(1ms并不重要),并且索引边界在解释上是相同的。因此我怀疑这里没有任何区别,所以坚持使用更易读的语法是个好主意