【问题标题】:Why sort document by id is slower with $match than not in mongodb?为什么使用 $match 按 id 排序文档比在 mongodb 中慢?
【发布时间】:2019-12-27 08:49:39
【问题描述】:

所以,我尝试查询

db.collection('collection_name').aggregate([
    {
        $match: { owner_id: '5be9b2f03ef77262c2bd49e6' }
    },
    {
        $sort: { _id: -1 }
    }])

上面的查询需要20s

但如果我尝试查询

db.collection('collection_name').aggregate([{$sort : {_id : -1}}])

仅需0.7秒

为什么没有 $match 的那个实际上比没有 match 快?

更新: 当我尝试这个查询时

db.getCollection('callbackvirtualaccounts').aggregate([
    {
        $match: { owner_id: '5860457640b4fe652bd9c3eb' }
    },
    {
        $sort: { created: -1 }
    }
])

只需要0.781s

为什么按 _id 排序比按创建字段排序慢?

注意:我使用的是 mongodb v3.0.0

【问题讨论】:

  • 因为$match 将扫描所有集合的文档以过滤它们,然后将$sort 应用于过滤的文档。
  • _id 是一个索引字段,$match 内的字段,即owner_id 可能没有索引。

标签: mongodb mongodb-query aggregation-framework aggregate


【解决方案1】:
db.collection('collection_name').aggregate([
{
    $match: { owner_id: '5be9b2f03ef77262c2bd49e6' }
},
{
    $sort: { _id: -1 }
}])

这个集合可能不会在 owner_id 上有索引;尝试使用下面提到的索引创建查询并重新运行您之前的代码。

db.collection('collection_name').createIndexes({ owner_id:1}) //Simple Index
 or 
db.collection('collection_name').createIndexes({ owner_id:1,_id:-1}) //Compound Index

**注意::如果您还不知道如何复合索引,您可以在匹配或排序中使用的所有键上单独创建简单索引,这也应该提高查询效率。

【讨论】:

  • 但是为什么当我尝试按创建的未索引字段排序时要快得多?
【解决方案2】:

查询速度取决于很多因素。集合的大小、文档的大小、集合上定义的索引(并在查询中正确使用)、硬件组件(如 CPU、RAM、网络)和查询运行时运行的其他进程。

您必须说明正在讨论的集合上定义了哪些索引以进行进一步分析。该命令将检索它们:db.collection.getIndexes()

注意_id字段的唯一索引是默认创建的,不能修改或删除。

(i)

但如果我尝试查询:db.collection.aggregate( [ { $sort : { _id : -1 } } ] ) 它是 只需 0.7 秒。

查询速度更快,因为_id 字段上有一个索引,并且它用于排序过程。聚合查询使用具有排序阶段的索引,并且当这种排序在管道的早期发生时。您可以通过生成查询计划来验证是否使用了索引(使用explainexecutionStats 模式)。生成的查询计划中会有索引扫描(IXSCAN)。


(ii)

db.collection.aggregate([
    {
        $match: { owner_id: '5be9b2f03ef77262c2bd49e6' }
    },
    {
        $sort: { _id: -1 }
    }
])

上面的查询需要20s。

当我尝试这个查询时,它只需要 0.781 秒。

db.collection.aggregate([
    {
        $match: { owner_id: '5860457640b4fe652bd9c3eb' }
    },
    {
        $sort: { created: -1 }
    }
])

为什么按 _id 排序比按创建字段排序慢?

根据现有信息无法得出任何结论。 一般来说,聚合查询早期出现的$match$sort 阶段可以使用在操作中使用的字段上创建的任何索引。

生成一个查询计划将揭示问题所在。

请以executionStats 模式运行explain,并发布所有相关查询的查询计划详细信息。有关于使用 explain 生成查询计划的 Mongodb v3.0.0 版本的文档:db.collection.explain()

【讨论】:

    猜你喜欢
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 2017-07-23
    • 2015-06-10
    • 2023-03-20
    • 2016-02-18
    • 2021-06-19
    相关资源
    最近更新 更多