Почему и когда необходимо перестроить индексы в MongoDB?

Некоторое время работал с MongoDB, и сегодня я сомневался во время обсуждения с коллегой.

Дело в том, что при создании индекса в MongoDB коллекция обрабатывается и создается индекс.

Индекс обновляется при вставке и удалении документов, поэтому я действительно не вижу необходимости запускать операцию индекса пересоединения (которая отбрасывает индекс, а затем восстанавливает его).

Согласно документации MongoDB:

Обычно MongoDB индексирует индексы во время обычных обновлений. Для большинства пользователей, команда reIndex не нужна. Однако это может стоить если размер коллекции существенно изменился или если индексы потребляют непропорциональное количество дискового пространства.

У кого-то возникла необходимость в выполнении операции индекса перестроения, которая стоит?

Ответы

Ответ 1

В соответствии с документацией MongoDB обычно нет необходимости регулярно восстанавливать индексы.

ПРИМЕЧАНИЕ. Любые советы по хранению становятся более интересными с MongoDB 3.0+, в котором представлен подключаемый API-интерфейс для хранения данных., Мои комментарии ниже относятся конкретно к механизму хранения MMAP по умолчанию в MongoDB 3.0 и более ранних версиях. У WiredTiger и других систем хранения есть разные реализации хранилищ данных и индексов.

При восстановлении индекса с помощью механизма хранения MMAP может быть полезно:

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

  • Вы хотите перейти от более старого формата индекса к более новому. Если реиндекс рекомендуется, это будет упомянуто в примечаниях к обновлению. Например, MongoDB 2.0 ввел значительные улучшения производительности индекса , поэтому в примечаниях к выпуску добавлен предлагаемый reindex в формат v2.0 после обновления. Точно так же MongoDB 2.6 представил индексы 2dsphere (v2.0), которые имеют различное поведение по умолчанию (разреженное по умолчанию). Существующие индексы не восстанавливаются после обновления версии индекса; выбор того, когда/когда обновляться, предоставляется администратору базы данных.

  • Вы изменили формат _id для коллекции в или из монотонно увеличивающегося ключа (например, ObjectID) до случайного значения. Это немного эзотерично, но есть оптимизация индекса, которая разбивает ведра b-tree 90/10 (вместо 50/50), если вы вставляете _id, которые всегда увеличиваются (ref: SERVER-983). Если характер вашего _id значительно изменится, может быть возможно построить более эффективное b-дерево с повторным индексом.

Дополнительную информацию об общем поведении B-дерева см.: Википедия: B-дерево

Визуализация использования индекса

Если вам действительно любопытно вникнуть в внутренности индекса немного больше, есть некоторые экспериментальные команды/инструменты, которые вы можете попробовать. Я ожидаю, что они ограничены только MongoDB 2.4 и 2.6:

Ответ 2

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

Общая идея индекса

При переходе от одного документа к другому, в полной коллекции документов, много времени и усилий пропадает из-за всех данных, которые не нужно решать. Если вы ищете документ с идентификатором "1234", перемещение по 100K + каждого документа делает его медленным.

Вместо того, чтобы искать все содержимое каждого документа в коллекции (физически перемещая головки чтения диска и т.д.), индекс делает это быстро. Это в основном пара ключ/значение, которая дает вам идентификатор и местоположение этого документа. MongoDB может быстро сканировать весь идентификатор в индексе, найти местоположения необходимых ему документов и напрямую загрузить их.

Выделение размера файла для индекса

Индексы занимают дисковое пространство, потому что они в основном представляют собой пару ключ/значение, хранящуюся в гораздо меньшем местоположении. Если у вас очень большая коллекция (большое количество элементов в коллекции), то ваш индекс растет в размере.

Большинство операционных систем выделяют куски дискового пространства в определенных размерах блоков. Большинство баз данных также выделяют дисковое пространство в больших кусках по мере необходимости.

Вместо того, чтобы увеличивать 100 тыс. размер файла при добавлении 100 тыс. документов, MongoDB, вероятно, вырастет 1 МБ или, может быть, 10 МБ или что-то еще - я не знаю, каков фактический размер роста. В SQL Server вы можете сказать, как быстро расти, а у MongoDB, вероятно, есть что-то подобное.

Увеличение количества кусков позволяет быстрее "вырастить" документы в пространстве, потому что база данных не нуждается в постоянном расширении. Если в базе данных теперь уже выделено 10 МБ пространства, она может просто использовать это пространство вверх. Он не должен продолжать расширять файл для каждого документа. Он просто должен записать данные в файл.

Это, вероятно, верно для коллекций и индексов для коллекций - все, что хранится на диске.

Размер файла и восстановление индекса

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

Если в индексе есть 10 000 элементов, а # 10 001 необходимо вставить, оно может быть вставлено в середину индексного файла. Теперь индекс должен перестроить себя, чтобы вернуть все в порядок. Это включает в себя перемещение большого количества данных вокруг, чтобы освободить место в конце файла и положить элемент № 10 001 в конец.

Если индекс постоянно избивается - много вещей удалено и добавлено - вероятно, быстрее просто увеличить размер индексного файла и всегда положить материал в конец. это быстро, чтобы создать индекс, но оставляет пустые отверстия в файле, где старые вещи были удалены.

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

Перестроить файл большого индекса

Для корректного уплотнения индексного файла до разумного размера может потребоваться много дискового доступа и операций ввода-вывода со всем по порядку. Перемещайте предметы из места в темное место, освободите место в нужном месте, переместите их обратно. Кстати, чтобы освободить место, вам пришлось переместить другие предметы в место временного размещения. Это рекурсивно и тяжело.

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

Большие изменения в размере коллекции

Предоставляя все, что я предполагаю выше, большое изменение в размере коллекции вызовет такой переполох. Если у вас есть 10 000 документов в коллекции, и вы удаляете 8 000 из них... ну, теперь у вас есть пустое место в вашем индексном файле, где раньше было 8 000 предметов. MongoDB необходимо переместить оставшиеся 2 000 предметов в физическом файле, чтобы перестроить его в компактной форме.

Вместо того, чтобы ждать около 8 000 пустых мест, которые нужно очистить, может быть быстрее перестроить с нуля с остальными 2000 пунктами.

Вывод? Может быть?

Таким образом, документация, которую вы цитировали, вероятно, будет иметь дело с потребностями "больших данных" или с большими коллекциями и индексами.

Также имейте в виду, что я делаю обоснованное предположение, основанное на том, что я знаю об индексировании, распределении диска, фрагментации файлов и т.д.

Моя догадка заключается в том, что "большинство пользователей" в документации означает, что 99,9% или более коллекций mongodb не нужно беспокоиться об этом.

специфический случай MongoDB

Согласно документации MongoDB:

Метод remove() не удаляет индексы

Итак, если вы удаляете документы из коллекции, вы тратите впустую дисковое пространство, если не перестроить индекс для этой коллекции.