MongoDB Много индексов против единого индекса в массиве поддокументов? - PullRequest
3 голосов
/ 24 октября 2011

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

Лучше ли иметь поле для каждой метки времени и индексировать каждое поле или сохранять метки времени и связанный с ними тип в поле массива и индексировать каждое поле этого массива?

Первый вариант, отдельные поля и индекс для каждого:

{
    "_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 голосов
/ 24 октября 2011

Это в основном сводится к тому, что 10 индексов размера N более эффективны, чем один индекс размера N * 10. Если вы просто смотрите на чтение, то отдельные индексы всегда должны быть быстрее. Связанные обходы b-дерева изучат меньший набор ключей и т. Д.

Есть пара моментов, которые следует учитывать:

  • Индексы в полях массива в основном индексируют каждый элемент массива отдельно. Таким образом, издержки поиска будут составлять не более 1-2 дополнительных шагов во время обхода b-дерева, что является незначительным ударом по производительности. Другими словами, они будут почти такими же быстрыми.
  • Наличие 10 индексов может означать, что для каждого обновления / вставки потребуется обновление более одного индекса (в зависимости от того, используют ли ваши индексы общее поле или если вы обновляете более 1 отметки времени одновременно). Это значительный фактор производительности.
  • Использование индекса массива облегчает добавление дополнительных временных меток (например, Timestamp10).
  • Существует ограничение на количество пространств имен, которые вы можете использовать на базу данных (24 КБ), и каждый индекс занимает одно. Если вы создадите отдельный индекс для каждого поля, это может стать проблемой.
  • Самое главное, индекс массива намного проще и упростит ваш код и, следовательно, удобство обслуживания. Учитывая ограниченные различия в производительности, я бы сказал, что это самая сильная мотивация для использования индекса массива здесь.
...