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

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

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

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

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

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

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

2 ответов


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

Примечание: любые советы по хранению становятся более интересными с MongoDB 3.0+, который представил pluggable API двигателя хранения. Мои комментарии ниже относятся конкретно к механизму хранения MMAP по умолчанию в MongoDB 3.0 и более ранних версиях. WiredTiger и другие механизмы хранения имеют различные реализации хранения данных & индексы.

может быть некоторое преимущество в восстановлении индекса с помощью mmap storage engine, если:

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

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

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

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

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

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


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

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

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

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

Выделение Размера Файла Для Индекса

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

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

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

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

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

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

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

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

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

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

Перестроить Для Большого Индексного Файла

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

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

Большое Изменение Размера Коллекции

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

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

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

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

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

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

конкретный случай MongoDB

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

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

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