0

假设我有 tx_collection 有 3 个文档,如下所示

{
    "block_number": 1,
    "value": 122
    "transfers": [
        {
            "from": "foo1", 
            "to": "bar1", 
            "amount": 111
        },
        {
            "from": "foo3", 
            "to": "bar3", 
            "amount": 11
        },
    ]
},
{
    "block_number": 2,
    "value": 88
    "transfers": [
        {
            "from": "foo11", 
            "to": "bar11", 
            "amount": 33
        },
        {
            "from": "foo22", 
            "to": "bar22", 
            "amount": 55
        },
    ]
},
{
    "block_number": 3,
    "value": 233
    "transfers": [
        {
            "from": "foo1", 
            "to": "bar1", 
            "amount": 33
        },
        {
            "from": "foo3", 
            "to": "bar3", 
            "amount": 200
        },
    ]
}

对于性能问题,我在transfers.amount

当我排序时transfers.amount

db.getCollection('tx_transaction').find({}).sort({"transfers.amount":-1})

我期望的文档顺序是按子字段的最大值排序transfers.amount

{
    "block_number": 3,
    "value": 233
    "transfers": [
        {
            "from": "foo1", 
            "to": "bar1", 
            "amount": 33
        },
        {
            "from": "foo3", 
            "to": "bar3", 
            "amount": 200
        },
    ]
},
{
    "block_number": 1,
    "value": 122
    "transfers": [
        {
            "from": "foo1", 
            "to": "bar1", 
            "amount": 111
        },
        {
            "from": "foo3", 
            "to": "bar3", 
            "amount": 11
        },
    ]
},
{
    "block_number": 2,
    "value": 88
    "transfers": [
        {
            "from": "foo11", 
            "to": "bar11", 
            "amount": 33
        },
        {
            "from": "foo22", 
            "to": "bar22", 
            "amount": 55
        },
    ]
}

由于只有 3 个文档,因此排序效果很好。排序顺序是我期望的块号 3 -> 块号 1 -> block_number 2

我的问题是,当有 1900 万个文档时,它会抛出错误消息

按摩就像

"errmsg" : "Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.",

排序时似乎没有使用多键索引。

你知道为什么会抛出这个错误信息吗?

JFYI。

  • 我的 mongodb 版本是 3.6.3
  • tx_collection 被分片
4

1 回答 1

2

从 MongoDB 3.6 及更高版本开始,我认为这是可以预期的,如使用索引对查询结果进行排序中所述:

由于在 MongoDB 3.6 中对数组字段的排序行为进行了更改,当对使用多键索引索引的数组进行排序时,查询计划包括一个阻塞排序阶段。新的排序行为可能会对性能产生负面影响。

在阻塞排序中,排序步骤必须先消耗所有输入,然后才能产生输出。在非阻塞或索引排序中,排序步骤扫描索引以按请求的顺序生成结果。

换句话说,“阻塞排序”意味着阶段的存在,SORT_KEY_GENERATOR阶段意味着内存中的排序。由于SERVER-19402 ,这已从 3.6 之前的 MongoDB 更改,以解决围绕数组字段排序的不一致问题。

有一张票可以改善这种情况:SERVER-31898。不幸的是,目前还没有针对这种行为的解决方法。

于 2019-10-10T03:00:58.097 回答