Почему мои запросы MongoDB работают медленно после добавления новых элементов в коллекцию?

Любая помощь в этом будет принята с благодарностью.

У меня есть большая коллекция Mongodb, в которой я храню действия пользователей. У нее есть несколько составных индексов для запросов, которые я хочу выполнить, и обычно производительность запросов фантастическая, а потоки активности пользователей загружаются немедленно.

Однако недавно я добавил фоновую задачу, которая добавляет в коллекцию 20 тыс. записей каждые 2 часа (по одной новой записи на пользователя). Поскольку эта задача была добавлена, я заметил, что при первом посещении моей ленты активности после добавления этих записей происходит огромная задержка перед загрузкой страницы. Затем, когда я обновляю страницу, она загружается быстро.

Кажется, что новые элементы добавляются в индекс только после того, как я пытаюсь получить к ним доступ. Но из того, что я прочитал в FAQ по MongoDB, они автоматически добавляются в индекс — http://docs.mongodb.org/manual/faq/indexes/#should-you-run-ensureindex-after-каждая-вставка. Возможно, дело в том, что их просто еще не добавили?

Вот статистика моей коллекции, если это поможет.

Array
(
[ns] => main.activities
[count] => 26280825
[size] => 3234981772
[avgObjSize] => 123.09285465734
[storageSize] => 4211892224
[numExtents] => 30
[nindexes] => 20
[lastExtentSize] => 844685312
[paddingFactor] => 1.001
[systemFlags] => 1
[userFlags] => 0
[totalIndexSize] => 25240448464
[indexSizes] => Array
    (
        [_id_] => 946551872
        [portfolio_id_1_type_1_timestamp_-1] => 1519746704
        [project_id_1_type_1_timestamp_1] => 1839902512
        [project_id_1] => 1148997808
        [piece_id_1] => 792794016
        [user_id_1_type_1_timestamp_-1] => 1903806128
        [type_1_timestamp_-1] => 1475522720
        [user_id_1_type_1] => 1440243280
        [project_id_1_type_1] => 1394008000
        [project_id_1_type_1_timestamp_1_project_page_timestamp_1] => 2114419888
        [project_id_1_type_1_project_page_timestamp_1] => 1564649296
        [conversation_id_1] => 870670416
        [project_comment_id_1] => 814640288
        [project_comment_id_1_type_1] => 1032408048
        [reply_to_comment_id_1] => 512324512
        [collection_id_1] => 822996160
        [user_id_1] => 1233578528
        [portfolio_id_1] => 852691392
        [type_1_user_id_1] => 1477182448
        [type_1_user_id_-1] => 1483314448
    )

[ok] => 1
)

person nlyn    schedule 20.07.2013    source источник


Ответы (1)


Я думаю, что наиболее вероятным ответом будет то, что фоновая задача вызывает выпадение документов из памяти при добавлении новых документов. Второй запрос быстрый, так как вы просто вытащили документы в память. Трудно сказать наверняка без более подробной информации о специфике документов и запросов, которые вы выполняете.

Если вы запускаете mongostat при первой загрузке страницы и видите ряд ошибок, вам нужно больше памяти.

Вы можете вернуть немного памяти, удалив некоторые индексы. В частности, следующие индексы могут быть удалены, поскольку они являются общим префиксом другого индекса:

    [project_id_1] => 1148997808
    [user_id_1_type_1] => 1440243280
    [project_id_1_type_1] => 1394008000
    [project_comment_id_1] => 814640288
    [user_id_1] => 1233578528
    [portfolio_id_1] => 852691392

Также один из этих индексов, вероятно, можно удалить, поскольку они отличаются только направлением последнего поля. Единственный случай, который не соответствует действительности, — это если ваше приложение сортирует результаты запроса как с {type: 1, user_id: 1}, так и с {type: 1, user_id:-1} в качестве документа сортировки.

    [type_1_user_id_1] => 1477182448
    [type_1_user_id_-1] => 1483314448

Существуют и другие индексы, которые могут быть удалены в зависимости от фактических запросов, которые вы выполняете.

ХТХ - Роб.

person Rob Moore    schedule 20.07.2013
comment
Спасибо, Роб, это помогает. Итак, судя по тому, что вы говорите: индекс «user_id_1_type_1_timestamp_-1» можно использовать так, как будто это 3 разных индекса: «user_id_1», «user_id_1_type_1» и «user_id_1_type_1_timestamp_-1» (например). Я понятия не имел, что это возможно. Это действительно должно сэкономить немного оперативной памяти. - person nlyn; 21.07.2013
comment
Да, точно. Его также можно использовать при обратном порядке: user_id_-1_type_-1_timestamp_1, user_id_-1_type_-1 и user_id_-1. - person Rob Moore; 21.07.2013