MongoDB много индексов против Один индекс в массиве вложенных документов?

#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 индекса. Индексы массива обрабатываются так же, как и любой другой индекс. Каждое значение в массиве индексируется отдельно.