【问题标题】:MongoDB Is searching for "null" faster than searching for "does not exist"?MongoDB 搜索“null”比搜索“不存在”更快吗?
【发布时间】:2012-06-10 16:21:40
【问题描述】:

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

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

查询 null 是否也应该被认为是低效的?

如果您知道要查找的字段存在但为空,那么编写是否更有效:

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

比:

db.foo.find( { "y" : null } )

假设该字段已编入索引

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

【问题讨论】:

    标签: mongodb nosql


    【解决方案1】:

    我不能肯定地说哪个更快,但是有一个thread in the news group 有人对$type-查询的性能有问题。

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

    1. 很难阅读和理解。即使是普通的 MongoDB 用户也可能不知道{type : 10} 是什么。
    2. 正如您已经指出的,语义是不同的。 $type 查询允许“两种不同类型的 null”,即字段不存在的文档和字段存在但为 null 的文档。反序列化后,这可能会在大多数语言中变成相同的对象,但 $type-query 会区分它们。
    3. 索引用于索引数据,而不是元信息。即使查询优化器能够映射它,我仍然会坚持更直接的解决方案。

    我认为另一个性能风险可能是 null 值的潜在低选择性:如果一半的文档具有某个值 y 并且一半的文档具有 null y,则查询 null 元素将返回一个很多文档,并且迭代游标可能很昂贵。但是,只有当有很多空值时,这才是正确的。

    【讨论】:

    • 我完全同意类型语法很糟糕,所以我想尽可能避免它。
    【解决方案2】:

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

    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 并不重要),并且在说明中的索引范围相同。因此我怀疑这里根本没有区别,所以坚持使用更易读的语法是个好主意

    【讨论】:

      猜你喜欢
      • 2015-10-24
      • 2011-05-13
      • 1970-01-01
      • 2013-07-31
      • 2014-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多