【问题标题】:Why does my ({$exists: true}) query take this long?为什么我的 ({$exists: true}) 查询需要这么长时间?
【发布时间】:2022-11-10 18:44:20
【问题描述】:

我有一个包含 2 亿个文档的集合。

我在 id 字段上添加了一个索引,该索引是一个使用 collection.createIndex({id: 1}) 的字符串字段

查询 db.collection.countDocuments();需要几秒钟并返回 207.713.493 的实际计数。

查询 db.collection.countDocuments({id: {$exists: false}});立即完成并返回 0(如预期的那样)。

但是,查询 db.collection.countDocuments({id: {$exists: true}});需要永远完成。现在它已经运行了 8 个小时,并且没有返回。

怎么会这样?结果应该很容易获得,因为它应该等于总数。

【问题讨论】:

  • 查询仍然需要对文档进行计数。带有 false 的条件立即返回,因为查询过滤器根据索引返回的文档很少或没有。有一个称为查询选择性的概念 - 这是关于在使用索引时可以通过查询检索到的文档数量。例如,如果您的查询返回少于 10%,则它的选择性还可以。如果查询返回 1%,则其选择性非常好。如果您的查询返回 90%,则它的选择性不好,并且索引没有多大用处 - 除了占用磁盘空间和内存。

标签: mongodb indexing


【解决方案1】:

根据to this AWS 文档:

Amazon DocumentDB 目前不支持将索引与 $ne、$nin、$nor、$not、$exists、$distinct 和 $elemMatch 运算符一起使用。因此,使用这些运算符将导致收集扫描。

这意味着每个文档都需要扫描才能执行计数。

这与 MongoDB 不同,后者允许对这些运算符进行索引。

例如,在 DocumentDB

db.collection.find({_id: {$exists: true}}).explain('executionStats')

返回

winningPlan: { stage: 'COLLSCAN' }

而在 MongoDB 上它返回(快得多):

winningPlan: { stage: 'IXSCAN' }

【讨论】:

    猜你喜欢
    • 2011-08-27
    • 1970-01-01
    • 2021-11-27
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多