#mongodb #indexing #mongodb-.net-driver
#mongodb #индексирование #mongodb-.net-driver
Вопрос:
Интересно, какой был бы более эффективный метод индексации различных временных меток моего документа, которые мне нужно отслеживать, имея в виду, что мое приложение довольно тяжелое при написании, но достаточно тяжелое при чтении, что без индексов запросы выполняются слишком медленно.
Лучше ли иметь поле для каждой временной метки и индексировать каждое поле или хранить временные метки и связанный с ними тип в поле массива и индексировать каждое поле этого массива?
Первый вариант, отдельные поля и индекс для каждого:
{
"_id" : "...",
"Field1.Timestamp" : '2011-01-01 01:00.000',
"Field2.Timestamp" : '2011-01-01 01:00.000',
"Field3.Timestamp" : '2011-01-01 01:00.000',
"Field4.Timestamp" : '2011-01-01 01:00.000',
"Field5.Timestamp" : '2011-01-01 01:00.000',
"Field6.Timestamp" : '2011-01-01 01:00.000',
"Field7.Timestamp" : '2011-01-01 01:00.000',
"Field8.Timestamp" : '2011-01-01 01:00.000',
"Field9.Timestamp" : '2011-01-01 01:00.000',
}
db.mycollection.ensureIndex({ "Field1.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field2.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field3.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field4.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field5.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field6.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field7.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field8.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field9.Timestamp" : 1 });
Затем есть массив временных меток и их статуса, содержащий только один индекс
{
"_id" : "...",
"Timestamps" : [
{ "Type" : "Field1", "Timestamp" : '2011-01-01 01:00.000' },
{ "Type" : "Field2", "Timestamp" : '2011-01-01 01:00.000' },
{ "Type" : "Field3", "Timestamp" : '2011-01-01 01:00.000' },
{ "Type" : "Field4", "Timestamp" : '2011-01-01 01:00.000' },
{ "Type" : "Field5", "Timestamp" : '2011-01-01 01:00.000' },
{ "Type" : "Field6", "Timestamp" : '2011-01-01 01:00.000' },
{ "Type" : "Field7", "Timestamp" : '2011-01-01 01:00.000' },
{ "Type" : "Field8", "Timestamp" : '2011-01-01 01:00.000' },
{ "Type" : "Field9", "Timestamp" : '2011-01-01 01:00.000' },
]
}
db.mycollection.ensureIndex({ "Timestamps.Type" : 1, "Timestamps.Timestamp" : 1 });
Неужели я здесь далек от истины? или какой из способов был бы лучше
Комментарии:
1. Как выглядят ваши запросы?
2. Запрос использует поле метки времени в сравнении $ LT: { «Field1Timetamp»: { $LT : «2011-01-01 01:00.000″ }, » BatchExpires» : { $ LT : «2011-01-01 01:00.000″ }, » Приоритет» : true } Индексы также будут включать два других поля, но для простоты я их не учел, поскольку их не так много (всегда будет только один BatchExpires и одно поле с приоритетом)
3. Я подумал, являются ли 2 индекса в массиве вложенных документов более эффективными, чем 9 или 10 индексов для полей, не входящих в массив…
4. Я думаю, что меньшее количество индексов, вероятно, будет лучшим подходом, но я не могу сказать наверняка, вероятно, стоит сравнить оба способа, если это критично.
Ответ №1:
Это в основном сводится к тому, что 10 индексов размера N более эффективны, чем один индекс размера N * 10. Если вы просто смотрите на чтение, то отдельные индексы всегда должны быть быстрее. Связанные обходы b-дерева будут проверять меньший набор ключей и т. Д.
Однако следует учитывать несколько моментов :
- Индексы в полях массива в основном индексируют каждый элемент массива отдельно. Таким образом, затраты на поиск будут составлять не более 1-2 дополнительных шагов во время обхода b-дерева, что является незначительным снижением производительности. Другими словами, они будут почти такими же быстрыми.
- Наличие 10 индексов может означать, что для каждого обновления / вставки потребуется обновить более одного индекса (в зависимости от того, используют ли ваши индексы поле или вы обновляете более 1 временной метки за раз). Это является важным фактором повышения производительности.
- Использование индекса массива немного упрощает добавление дополнительных временных меток (например, Timestamp10).
- Существует ограничение на количество пространств имен, которые вы можете использовать для каждой базы данных (24 кб), и каждый индекс занимает одно пространство. Если вы создадите отдельный индекс для каждого поля, это может стать проблемой.
- Самое главное, что индекс массива намного проще и упростит ваш код и, следовательно, удобство обслуживания. Учитывая ограниченные различия в производительности, я бы сказал, что это самая сильная мотивация для использования индекса массива здесь.
Комментарии:
1. Итак, вы предполагаете, что для ОБНОВЛЕНИЯ / ВСТАВКИ наличие одного отдельного индекса должно быть намного быстрее, чем 10 отдельных индексов? Я не был уверен, были ли дополнительные накладные расходы на обновление индекса, если это был массив индексируемых объектов… На самом деле у меня никогда не должно быть больше, скажем, 20 полей, которые нуждались бы в индексации, но, похоже, это слишком много полей для индексации…
2. Это быстрее, если альтернатива будет означать, что необходимо обновить более 1 индекса. Индексы массива обрабатываются так же, как и любой другой индекс. Каждое значение в массиве индексируется отдельно.