Статьи

Индексные стратегии MongoDB и типы индексов

1. Стратегии индексов MongoDB и типы индексов — Введение

MongoDB — это кросс-платформенная база данных с открытым исходным кодом, ориентированная на документы и разработанная на C ++, которая является одной из самых популярных и используемых баз данных типа NoSQL. Он работает поверх JSON-подобных документов с парами ключ-значение, схема которых может оставаться неопределенной в каждом документе. Кроме того, его можно использовать бесплатно, так как он публикуется под сочетанием Стандартной общественной лицензии GNU Affero и Лицензии Apache.

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

2. Что такое индекс?

Индекс в базе данных позволяет запросам находить и фильтровать данные гораздо эффективнее и быстрее, чем тот запрос, который мог бы выполняться без присутствия индекса. Простейший пример индекса — это то, что мы все уже использовали в наших книгах. В начале каждой книги есть «Оглавление», которое помогает читателям найти номера страниц тем, представленных в этой книге. Чтобы прочитать тему, нам просто нужно найти ее в оглавлении, которое представляет собой упорядоченный список тем, и мы можем получить номер страницы из этого. Индексы работают таким же образом. Поскольку в таблице может быть несколько столбцов (или коллекция в случае MongoDB), индекс может быть сформирован для любого из столбцов, присутствующих в коллекции.

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

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

3. Типы индексов в MongoDB

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

3.1 Индекс одного поля

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

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

Индекс одного поля

1
db.books.createIndex( { book_name: 1 } )

В приведенном выше запросе число 1 указывает порядок индекса (что на самом деле не имеет значения, поскольку MongoDB может считывать индекс в обоих направлениях).

3.2 Составной индекс

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

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

Составной индекс

1
db.books.createIndex( { price: 1, book_name: 1 } )

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

Составной индекс

1
db.books.createIndex( { book_name: 1, price: 1 } )

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

3.3 Multikey Index

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

Когда содержимое массива проиндексировано, MongoDB взрывает массив, создает несколько полей с одинаковыми именами, каждое из которых содержит разные значения в этом массиве:

Стратегии индекса MongoDB - Взрыв массива в индексе MongoDB

Взрыв массива в индексе MongoDB

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

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

3.4 Геопространственный индекс

MongoDB позволяет нам сохранять геопространственные формы в наших базах данных, позволяя нам хранить коллекцию Geo-JSON в документах. Для эффективного запроса геопространственных данных MongoDB предоставляет два типа внутренних индексов:

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

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

3.5 Текстовый указатель

MongoDB также предоставляет возможность создавать индексы для текстовых полей, что также поддерживает поиск некоторого строкового содержимого в коллекции. Следует отметить, что в этих индексах не хранятся стоп-слова, такие как «the», «a», «or». В текстовом указателе слова хранятся только для хранения корневых слов. Мы можем использовать следующий запрос для создания текстового индекса на поле:

Текстовый указатель

1
db.books.createIndex( { book_name: "text" } )

Если для индексирования текстового поля вы используете язык, отличный от английского, мы можем использовать запрос:

Текстовый указатель с языком

1
db.books.createIndex( { book_name: "text" }, { default_language: "french" } )

Текстовый индекс нечувствителен к регистру и диакритическим знакам. Версия 3 текстового индекса (та, которая поставляется с версией 3.4) поддерживает обычные C, простые S и специальные свертки регистров T, как описано в сворачивании регистров Unicode Character Database 8.0. В дополнение к нечувствительности к регистру, версия 3 текстового индекса поддерживает диакритическую нечувствительность.

Благодаря высокопроизводительному критерию text-index, MongoDB бросает серьезный вызов Elasticsearch, который является базой данных, в основном используемой для запросов текстового поиска.

3.5 Хешированный индекс

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

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

4. Свойства индекса в MongoDB

Поведение индекса можно изменить в MongoDB, указав конкретные свойства для этого индекса. Некоторые из этих свойств:

4.1 Уникальный индекс

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

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

4.2 Частичный индекс

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

Следует отметить, что запрос будет выполняться к частичному индексу, только если полный запрос может быть удовлетворен частичным индексом.

4.3 Разреженный индекс

Свойство sparse индекса гарантирует, что индекс содержит запись только для документов, которые фактически содержат индексированное поле. Разреженный индекс полностью пропускает документы, которые не имеют индексированного поля.

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

4.4 Индекс TTL

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

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

5. Ограничения индексов

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

  1. Одна коллекция в MongoDB может иметь только максимум 64 индекса. Это становится проблемой, когда размер документа большой, и нам, возможно, придется разбить наши документы на несколько коллекций.
  2. Полное имя индекса в документе не может содержать более 128 символов. FQN для индекса состоит из <db_name>.<collection-name>.$<index_name> .
  3. В составном индексе не может быть более 31 поля.
  4. Запрос MongoDB не может использовать как текстовые, так и геопространственные индексы. Мы не можем объединить оператор $text с любым другим оператором, связанным со специальным индексом. Например, оператор $text оператор $near нельзя использовать вместе.
  5. Поля с двумерными сферическими индексами могут содержать только данные геометрии. Таким образом, точки на плоской системе координат [x, y] разрешены. Для негеометрий операция запроса данных не будет выполнена, если в этом индексе будут сохранены данные любого другого типа.
  6. Поскольку данные в индексе в основном хранятся в оперативной памяти, когда работает экземпляр MongoDB, они могут занимать большой объем памяти на компьютере. Это также делает индексы MongoDB чрезвычайно быстрыми.
  7. По умолчанию индексы MongoDB сделаны на переднем плане. Это означает, что все операции с коллекциями блокируются до полного построения индекса. Однако это поведение можно изменить, указав в запросе свойство создания фона.

6. Заключение

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

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

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