简体   繁体   中英

MongoDB - Aggregation match and sort - very slow on empty match (with indexes)

I building an application in PHP with MongoDB. The table I am having issues on has ~1million rows.

MongoDB shell version v4.2.0
git version: a4b751dcf51dd249c5865812b390cfd1c0129c30

I use aggregation to select rows that match my criteria. After the matching stage I use sort to arrange the response elements but it takes 20 seconds to execute if after the matching stage I have an empty response.

I've tried to use unwind but and it fixed the the issue, but it raised another. If there are matching documents the query will become slow.

CASE 1:

db.getCollection("article_copy").aggregate([
    {$match: {'sections.related': ObjectId('5de3699c3019d0978901f355')}},
    {$sort: {_id: -1}}

])

The match stage will not match any documents and it takes 20s to execute. The aggregation with only the match (without sort) executes instantly as I do have an index on sections.related.

CASE 2:

db.getCollection("article_copy").aggregate([
    {$match: {'sections.related': ObjectId('5db3699c3019d0978901f255')}},
    {$sort: {_id: -1}}
])

In this case I do have matching documents and the aggregation is blazing fast (less than 0.03s).

Example of document:

{ 
    "_id" : ObjectId("5db1da921d88bc6ee50460be"), 
    "id" : NumberInt(2228550), 
    .
    .
    .
    .
    "sections" : [
        {
            "related" : ObjectId("5db3699c3019d0978901f255"), 
            "order" : NumberInt(1), 
            "type" : NumberInt(1)
        }, 
        {
            "related" : ObjectId("5db3699c3019d0978901f256"), 
            "order" : NumberInt(1), 
            "type" : NumberInt(1)
        }
    ],
}

Note: I do have idexes on: - section.related

Indexes:

```/* 1 */
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "dbTests.article_copy"
    },
    {
        "v" : 2,
        "key" : {
            "homeOrder" : 1
        },
        "name" : "homeOrder asc",
        "ns" : "dbTests.article_copy"
    },
    {
        "v" : 2,
        "key" : {
            "sections.order" : 1
        },
        "name" : "test",
        "ns" : "dbTests.article_copy"
    },
    {
        "v" : 2,
        "key" : {
            "sections.related" : 1
        },
        "name" : "secrel_asc",
        "ns" : "dbTests.article_copy"
    },
    {
        "v" : 2,
        "key" : {
            "sections.related" : -1
        },
        "name" : "secrel_desc",
        "ns" : "dbTests.article_copy"
    },
    {
        "v" : 2,
        "key" : {
            "sections.order" : -1
        },
        "name" : "secord_desc",
        "ns" : "dbTests.article_copy"
    },
    {
        "v" : 2,
        "key" : {
            "sections.type" : 1
        },
        "name" : "type_acs",
        "ns" : "dbTests.article_copy"
    },
    {
        "v" : 2,
        "key" : {
            "_id" : -1,
            "sections.related" : -1
        },
        "name" : "id_sec",
        "ns" : "dbTests.article_copy"
    },
    {
        "v" : 2,
        "key" : {
            "author_id" : 1
        },
        "name" : "auth_asc",
        "ns" : "dbTests.article_copy"
    },
    {
        "v" : 2,
        "key" : {
            "article_status" : 1
        },
        "name" : "art_stat_asc",
        "ns" : "dbTests.article_copy"
    }
]```

The fix was to add a multiple index. Although I have separate indexes on _id and sections.related, only after I've create a multiple index with the both of them the query became efficiend.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM