Ответ
Да, работал. Индексы в MongoDB — это специальные структуры данных, которые хранят небольшую часть данных коллекции в упорядоченном виде. Их основная цель — кардинально ускорить операции поиска и сортировки. Однако они замедляют операции записи (вставка, обновление, удаление), так как при каждом изменении документа СУБД нужно обновлять и индексы.
Основные типы индексов:
- Single Field: Индекс по одному полю. Самый простой и распространённый тип.
- Compound: Составной индекс по нескольким полям. Порядок полей в индексе критически важен! Правило
ESR(Equality, Sort, Range) помогает выбрать правильный порядок: сначала поля для точного совпадения, затем для сортировки, и в конце — для диапазонных запросов. - Multikey: Создаётся для полей, содержащих массивы. MongoDB создаёт отдельную запись в индексе для каждого элемента массива.
- Text: Для реализации полнотекстового поиска по строковым полям.
- Geospatial: Для запросов, связанных с геоданными (поиск по координатам, в радиусе и т.д.).
- TTL (Time-To-Live): Специальный индекс, который позволяет MongoDB автоматически удалять документы по истечении определённого времени.
- Unique: Гарантирует, что значения индексируемого поля (или комбинации полей) будут уникальными в коллекции.
Пример создания индекса в Go:
// Создание уникального составного индекса по полям 'username' (по возрастанию) и 'email' (по убыванию)
indexModel := mongo.IndexModel{
Keys: bson.D{
{Key: "username", Value: 1}, // 1 для ascending
{Key: "email", Value: -1}, // -1 для descending
},
Options: options.Index().SetUnique(true),
}
_, err := collection.Indexes().CreateOne(context.Background(), indexModel)
Как я оптимизирую запросы:
- Анализ запросов: Использую метод
explain("executionStats")для анализа плана выполнения запроса. Он показывает, используются ли индексы, сколько документов было просканировано (totalDocsExamined) и сколько возвращено (nReturned). В идеале эти два числа должны быть близки. - Покрывающие запросы (Covered Queries): Стараюсь строить индексы так, чтобы они включали все поля, необходимые для запроса (и в
find, и вprojection). В этом случае MongoDB может вернуть результат прямо из индекса, не обращаясь к самим документам, что очень быстро. - Правильный выбор полей для индекса: Индексирую поля, по которым часто происходит фильтрация (
find), сортировка (sort) и агрегация ($lookup,$group). - Контроль количества индексов: Избегаю создания избыточных индексов, так как каждый из них потребляет память и замедляет операции записи.
Ответ 18+ 🔞
А, индексы в MongoDB, ну это же классика, блядь! Это как если бы ты в своей библиотеке из овердохуища книг решил не рыться по всем полкам, а завел картотеку, где всё по полочкам разложено. Картотека — это индекс, сука. Без неё каждый запрос — это пиздец, ад и Израиль, надо весь шкаф перелопатить. А с ней — чик-чик, и готово.
Но, как водится, за всё хорошее надо платить, ёпта. За скорость чтения ты платишь скоростью записи. Потому что когда ты новую книжку на полку суёшь, тебе надо и в картотеку новую карточку впиздючить. Законы физики, нихуя не попишешь.
Основные типы этих самых картотек-индексов:
- Single Field (По одному полю): Самый простой, дедовский способ. Индексируешь, например,
username. Ищешь Васю — быстро. Ищешь Петю — тоже быстро. Просто, как три копейки. - Compound (Составной, ёбаный): Вот тут уже начинается магия, а для многих — пиздец и боль. Индекс сразу по нескольким полям, например,
cityиsalary. И запомни раз и нахуй: порядок полей — ВСЁ! Есть правилоESR(Equality, Sort, Range). Сначала поля, где ищешь точное совпадение (город), потом для сортировки (дата), и в самом конце — для диапазонов (зарплата от и до). Нарушишь порядок — получишь индекс, который нихуя не работает, а только место жрёт. - Multikey (Многоключевой): Для полей-массивов. Завёл у человека теги
["go", "beer", "mongodb"]. MongoDB возьмёт и для каждого элемента массива отдельную запись в индекс впендюрит. Удобно искать всех, кто любит пиво. - Text (Текстовый): Чтобы искать не только по точному совпадению, а по смыслу, словам. Для этого и нужен текстовый индекс, он умеет в стемминг, игнорирование стоп-слов и прочую хуйню.
- Geospatial (Гео-индекс): Ищешь все бары в радиусе километра от своего дивана? Вот для этого инструмент. Индексируешь координаты и потом тыкаешь запросом «найди всё рядом».
- TTL (Индекс с сроком годности): Гениальная штука, блядь! Создаёшь индекс с временем жизни. MongoDB сама, как ответственный дворник, будет подходить и удалять устаревшие документы. Автоматически, нахуй! Хранишь сессии или временные логи — идеально.
- Unique (Уникальный): Железобетонная гарантия, что значения, например, в поле
email, не повторятся. Попробуй вписать уже существующий email — получишь в ебало ошибку. Порядок наводит.
Вот тебе пример, как эту хуйню на Go создать:
// Делаем уникальный составной индекс: username по возрастанию, email по убыванию.
indexModel := mongo.IndexModel{
Keys: bson.D{
{Key: "username", Value: 1}, // 1 — это по возрастанию
{Key: "email", Value: -1}, // -1 — это по убыванию, да, так можно
},
Options: options.Index().SetUnique(true), // Говорим: "Будь уникальным, сука!"
}
_, err := collection.Indexes().CreateOne(context.Background(), indexModel)
А теперь, как я обычно эту банду оптимизирую, чтобы всё летало:
- Вскрытие покажет:
explain(). Это твой лучший друг и детектор пиздежа. Запускаешь запрос сexplain("executionStats")и смотришь, блядь: сколько документов пришлось перерыть (totalDocsExamined), а сколько вернул (nReturned). Если перерыл миллион, а вернул десять — это пиздец, индекс либо кривой, либо его нет. Надо чинить. - Покрывающие запросы — мечта идиота (в хорошем смысле). Суть в том, чтобы индекс содержал ВСЕ поля, которые нужны для ответа. Тогда MongoDB, хитрая жопа, даже не полезет в сами документы, а всё возьмёт прямо из индекса. Скорость — космос.
- Индексируй с умом, а не похуй. Часто фильтруешь по
statusи сортируешь поcreated_at? Значит, тебе скорее всего нужен составной индекс{ status: 1, created_at: 1 }. Не индексируй всё подряд, каждый индекс — это как лишний рюкзак на спине при записи. - Не умножай сущности без необходимости. Помни: каждый новый индекс — это тормоза на записи и пожиратель памяти. Создал индекс — прикинь, сколько пользы он принесёт против вреда. Иногда проще один сложный запрос подождать, чем всю систему на колени поставить ради него.
Вот так вот, если коротко и с матом. Главное — понимать, что индекс не волшебная таблетка, а инструмент. Им можно и дом построить, и себе по ебалу получить, если не умеешь.