mongodb multikey index кажется, что не используется при сортировке - PullRequest
0 голосов
/ 10 октября 2019

Давайте предположим, что у меня есть 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 -> номер_блока 2, который я ожидал

Моя проблема в том, что при наличии 19 миллионов документов выдается сообщение об ошибке

Массаж похож на

"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 *

1 Ответ

0 голосов
/ 10 октября 2019

Начиная с MongoDB 3.6 и новее, я думаю, что этого следует ожидать, как указано в Использование индексов для сортировки результатов запроса , где указано:

В результате измененийДля сортировки поведения в полях массива в MongoDB 3.6, при сортировке массива, индексированного по многокнопочному индексу, план запроса включает в себя этап SORT блокировки. Новое поведение сортировки может отрицательно повлиять на производительность.

При блокировке SORT все входные данные должны быть использованы на этапе сортировки, прежде чем он сможет выдавать выходные данные. В неблокирующей или индексированной сортировке шаг сортировки сканирует индекс для получения результатов в запрошенном порядке.

Другими словами, «блокирующая сортировка» означает наличие стадии SORT_KEY_GENERATORЭтап, который означает сортировку в памяти. Это было изменено с MongoDB до 3.6 из-за SERVER-19402 для устранения несоответствий при сортировке поля массива.

Есть способ исправить эту ситуацию: SERVER-31898. К сожалению, пока нет обходного пути для этого поведения.

...