Индекс MongoDB и детали оптимизации

MongoDB

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

технический блог: Стек технологий Node.js

Быстрая навигация

Руководство по собеседованию

  • 生产环境如何正确创建索引?,Ссылаться на:#

Тип индекса MongoDB

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

1. Индекс _id

Большинство коллекций индексируются по умолчанию, и для каждой вставленной информации MongoDB создает уникальное поле _id.

Например, при создании новой коллекции

db.demo_admin2.insert({x:1})
db.demo_admin2.getIndexes() # 查看集合索引,可看到_id索引

2. Единый ключевой индекс

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

Например, запись в виде: {x:1,y:2,z:3}, пока индекс установлен в поле x, вы можете использовать x в качестве условия для запроса

db.demo_admin2.ensureIndex({x:1}) # 创建索引
db.demo_admin2.find({x:1}); # 使用索引查询

3. Многоключевой индекс

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

db.demo_admin2.insert({x:[1,2,3,4]})

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

При наличии нескольких условий запроса необходимо установить составной индекс.

вставить запись{'x':1,'y':2,'z':3}

db.demo_admin2.insert({'x':1,'y':2,'z':3});

создать индекс

db.demo_3.ensureIndex({x:1,y:1}) # 1升序,-1降序

использовать{x:1,y:1}запрос как условие

db.demo_admin2.find({x:1,y:2})

5. Просроченный индекс

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

5.1 Создание просроченного индекса

При создании индекса необходимо использовать еще один параметр для уточнения эффективного времени индекса - EXPIREAEAPTERSECONDS, в считанные секунды

Следующий примерtimeПоля создают просроченные индексы

db.demo_3.ensureIndex({time:1},{expireAfterSeconds:10})

5.2 Истекшие лимиты индекса

  • Значение поля индекса с истекшим сроком действия должно быть указанного типа времени и должно быть массивом ISODate или ISODate.Временные метки использовать нельзя, иначе они не могут быть удалены автоматически.

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

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

db.demo_3.ensureIndex({time:1},{expireAfterSeconds:30}
db.demo_3.insert({time:new Date()});

6. Полнотекстовое индексирование

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

6.1 Создание полнотекстового индекса

Метод создания полнотекстового индекса аналогичен созданию индекса с одним ключом и составного индекса. значение заменено на «текст», $** соответствует всем элементам в наборе

Создание полнотекстового индекса для поля

db.articles.ensureIndex({key:"text"})

Создание полнотекстового индекса для нескольких полей

db.articles.ensureIndex({key_1:"text"},{key_2:"text"})

Создайте полнотекстовый индекс для всех полей в коллекции

db.articles.ensureIndex({"$**":"text"})

6.2 Примеры

показатель

db.article.ensureIndex({"article":"text"})
db.articles.find({$text:{$search:"coffee"}})
db.articles.find({$text:{$search:"aa bb cc"}}) # 包含aa或bb或cc的数据
db.articles.find({$text:{$search:"aa bb -cc"}}) # 同时包含aa、bb且不包含cc的数据
db.articles.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}})# 同时包含aa、bb、cc的数据(用""包裹起来,引号需要用反斜杠\转义)

6.3 запрос подобия mongodb

$metaоператор:{score:{$meta:'textScore'}}

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

db.article.find({$text:{$search:"aa bb ff"}},{score:{$meta:"textScore"}})

Плюс метод .sort можно сортировать

db.article.find({$text:{$search:"aa bb ff"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})

6.4 Ограничения глобальных индексов

  1. Для каждого запроса можно указать только один$textЗапрос
  2. $textзапрос не может отображаться в$norзапрос
  3. Если запрос содержит$text, hintбольше не работает
  4. Полнотекстовый индекс MongoDB пока не поддерживает китайский язык

7. Геоиндексация

  • 2d индекс для запоминания и нахождения точек на плоскости
  • Индекс 2dsphere для хранения и поиска точек на сфере

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

1. Имя атрибута индекса

MongoDB будет создана автоматически, правило key_1 или key_-1 1 или -1 представляет направление сортировки, обычно мало влияет, а длина обычно ограничена 125 байтами.

db.collection.ensureIndex({indexValue},{name: key})

Мы можем назвать себя

db.demo_3.ensureIndex({x:1,y:1,z:1,n:1},{name:'xyz-name'});

падение индекса

db.demo_3.dropIndex(indexName)

2. Задается уникальная уникальность атрибута индекса

Уникальные ограничения, такие как поля реляционной базы данных

db.demo_3.ensureIndex({m:1,n:1},{unique:true})

Проверка экземпляра индекса

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

  • Создать тестовые данные
> for(var i=0; i<5000000; i++) db.demo_user.insert({id: i})
WriteResult({ "nInserted" : 1 })
  • Неиндексированный запрос данных

В случае отсутствия индексации время выполнения запроса данных занимает более 6 секунд.

图片描述

  • Запрос данных путем индексации
db.getCollection('demo_user').ensureIndex({"id": 1}) # 建立索引

На рисунке ниже показана ситуация с индексацией: запрос данных занимает всего 0,001 секунды, что показывает важность индексации.

图片描述

Блокировки на уровне библиотеки, вызванные индексами

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

Построение индекса в MongoDB — это процесс запуска блокировок записи.Обычно, чем больше объем данных, тем больше время блокировки записи занимает созданный индекс.Существует два способа построения индексов в MongoDB.

  • создан передний план (ошибка)

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

db.getCollection('demo_user').ensureIndex({"id": 1}) # 建立索引

图片描述

  • Создание фона (рекомендуется)Метод создания индекса на основе фона После выполнения команды создания индекса открывается новый терминал для запроса данных в другой коллекции, и данные могут быть немедленно возвращены.
db.getCollection('demo_user').ensureIndex({"id": 1}, {background: 1}) # 建立索引

图片描述

Автор: Мэй Джун
Ссылка на сайт:Вухуу. ИМО OC.com/article/285…
Источник: МООК
Github: Стек технологий Node.js

Рекомендуемое чтение