#mongodb #mongoose #indexing
#mongodb #мангуст #индексирование
Вопрос:
Мне нужно создать индекс для следующего запроса:
await Activity.find({
$and: [
{
lastUpdated: {
$gte: new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000),
},
},
{
"followers._user": _user,
},
{
global: true,
}
]
})
.collation({
locale: "en_US",
numericOrdering: true,
})
.sort({
lastUpdated: -1
})
.skip(
length
)
.limit(
10
)
В настоящее время у меня есть приведенный ниже индекс, но запрос его не использует.
ActivitiesSchema.index(
{ "followers._user": 1, global: 1, lastUpdated: -1 },
{
collation: {
locale: "en_US",
numericOrdering: true,
},
}
);
Что я могу попытаться решить?
Комментарии:
1. Как вы узнаете, используется он или нет? Обычно я бы выполнил запрос в MongoShell, используя explain(), чтобы увидеть, как планировщик ожидает выполнения запроса. Вы проверили, что индекс был создан? Вообще говоря, создание индексов в вашем приложении — плохая практика, поскольку создание индекса может создать нагрузку на загруженную систему. Вместо того, чтобы приложение создавало индекс, рекомендуется создавать индекс в нерабочее время. При использовании MMS (Atlas, Ops Manager) вы можете применять индекс в скользящем режиме с небольшим воздействием на производственную систему.
2. @barrypicker Я поддерживаю каждое слово относительно управления индексами на уровне приложений, но сообщество Mongoose придерживается несколько иного мнения по этому вопросу mongoosejs.com/docs/guide.html#indexes . Они рекомендуют отключить автоматическое обновление индекса в производственных системах, поэтому было бы несправедливо называть это «плохой практикой» и вводить в заблуждение людей, которые только начали изучать этот довольно популярный ODM.
3. @barrypicker Атлас показывает мне, что он не использовался в течение X дней, вот откуда я знаю. По какой-то причине я не могу заставить explain() работать на меня, но я вижу объяснение на вкладке профиля в Atlas, которое показывает мне, что более 2 тыс. записей (все они) сканируются и возвращаются. Я слышу вас с созданием индексов, но это единственное бизнес-приложение, расположенное в одной области и оказывающее очень незначительное влияние на производственную систему, поскольку я делаю обновления в нерабочее время.
4. Вам не нужен индекс, если вся ваша коллекция содержит только 2 тыс. документов.
5. @AlexBlex Я знаю это для производства. Это числа из моей базы данных разработки.
Ответ №1:
Измените индекс на:
{ lastUpdated: -1, "followers._user": 1, global: 1 }
ПРИМЕЧАНИЕ: это может повлиять на другие запросы, которые полагаются на существующий индекс
https://docs.mongodb.com/manual/tutorial/sort-results-with-indexes/#sort-and-index-prefix читает:
Если ключи сортировки соответствуют ключам индекса или префиксу индекса, MongoDB может использовать индекс для сортировки результатов запроса. Префикс составного индекса — это подмножество, состоящее из одного или нескольких ключей в начале шаблона ключей индекса.
Поскольку вы сортируете по «lastUpdated», индекс должен начинаться с него.
ПРИМЕЧАНИЕ 2: с этим изменением Mongodb может использовать, но это не гарантируется. Существует много других факторов, таких как избирательность и мощность, например global: true,
, подразумевает чрезвычайно низкую мощность, чтобы извлечь выгоду из индекса в этом поле. С другой стороны, если пользователь мало подписывается, а общая активность велика, может быть дешевле отфильтровать по индексу «followers._user» и выполнить сортировку в памяти. Планировщик запросов должен решить, какой индекс использовать.
Комментарии:
1. Это сделало это! Спасибо!