Использование индекса с первым оператором группы Mon go - PullRequest
1 голос
/ 22 апреля 2020

за месяц * Последняя документация по группе , существует специальная оптимизация для $ first:

Оптимизация для возврата первого документа каждого Группа

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

Это имеет смысл, поскольку для каждой ячейки должна быть только первая запись в упорядоченном индексе. в групповой стадии $. К сожалению, в моем тестировании я получил запрос, который обрабатывает ~ 800 тыс. Отсортированных записей примерно за 1 с, а затем передает их в $ group, где требуется около 10 с для вывода выходных документов 1,7 тыс. Для некоторых значений key (см. пример ниже). Для других значений key время ожидания составляет 300 с. В группе должно быть ровно 1704 бина, независимо от key, и эти бины запроса должны охватываться первыми тремя записями в индексе, насколько я могу судить. Я что-то упустил?

db.getCollection('time_series').aggregate([
    {
        '$match': {
            'organization_id': 1,
            'key': 'waffle_count'
        }
    },
    {
        '$sort': {
            'key': 1, 'asset_id': 1, 'date_time': - 1
        }
    },
    {
        '$group': {
            '_id': {
                'key': '$key', 'asset_id': '$asset_id'
            },
            'value': {
                '$first': '$value'
            }
        }
    }
]);

Вот индекс:

{
    "organization_id": 1,
    "key": 1,
    "asset_id": 1,
    "date_time": -1
}

1 Ответ

1 голос
/ 23 апреля 2020

Я отправил запрос в службу поддержки Atlas MongoDB. Оптимизация, которую я цитировал, недоступна до версии 4.2 (мы используем 3.6). Поддержка цитирования Atlas:

Упомянутое вами усовершенствование было реализовано в 4.2 через SERVER-9507 . В вашем конкретном примере вам, возможно, понадобится внедрить SERVER-40090 , чтобы ваш конвейер мог в полной мере воспользоваться преимуществами улучшения. Мы сообщим команде о ее потенциальной выгоде для вашей конкретной c ситуации.

На данный момент вторая проблема не устранена и требует простой установки $ group _id, такой как:

'_id': 'asset_id': '$asset_id'

Принимая во внимание, что ключ, указанный в качестве объекта, не сможет использовать индекс, даже если это не составной ключ, например:

'_id': { 'asset_id': '$asset_id' }
...