Создание составных индексов MongoDB для нескольких полей с некоторым перекрытием? - PullRequest
1 голос
/ 03 марта 2012

Я новичок в MongoDB и пытаюсь убедиться, что настроил правильные индексы.Я видел подобные вопросы о составных индексах здесь, но ни один из них точно не описывает ситуацию, в которой я нахожусь.

Примечание: Я использую Rails 3.2 и Mongoid.

У меня есть коллекция событий, которые всегда сортируются (и часто ищутся) по дате, но, как правило, также с другим параметром.Например, я мог бы хотеть найти События, которые соответствуют определенному набору категорий в пределах определенного диапазона дат;или я мог бы хотеть найти События, которые соответствуют определенному человеку в пределах определенного диапазона дат.Типы поиска будут:

  1. Всегда по дате (или, по крайней мере, сортировка по дате)
  2. Часто по категории
  3. Иногда дополнительно по [человек, место,или ключевое слово]

Первым решением, которое я придумал, было несколько составных ключей, которые начинаются с даты и категории, например так:

class Event
...

index ([
    [:date, Mongo::DESCENDING], 
    [:category_id, Mongo::ASCENDING]
    ["people.person_id", Mongo::ASCENDING]
  ])
index ([
    [:date, Mongo::DESCENDING], 
    [:category_id, Mongo::ASCENDING]
    [:venue_id, Mongo::ASCENDING]
  ])
index ([
    [:date, Mongo::DESCENDING], 
    [:category_id, Mongo::ASCENDING]
    [:keywords, Mongo::ASCENDING]
  ])

Но это кажется немного смешнымчтобы я продолжал перекрывать индекс "date + category_id", а также о случаях, когда я не ищу по category_id?

UPDATE: dcrosta спросил, чтокакие запросы будут выполняться, и как часто.Не зная точно, могу предположить, что это будет выглядеть примерно так:

Очень часто:

  • по дате
  • по дате+ категория
  • по дате + ключевое слово
  • по дате + категория + ключевое слово

Довольно часто:

  • по дате + человек
  • по дате + место проведения

Реже:

  • по дате + категория + место проведения
  • по дате + категория + человек

1 Ответ

3 голосов
/ 05 марта 2012

ОК, учитывая эти запросы, вот индексы, которые я бы создал:

db.events.createIndex({date: 1, category: 1})
db.events.createIndex({date: 1, keyword: 1})

Любой из этих запросов можно использовать только для запросов date, а любой можно использовать для date+ category + keyword.Какой из них будет выбран в последнем случае, будет зависеть от избирательности этих двух полей и конкретного рассматриваемого запроса.

Вы также можете захотеть индекс для date сам по себе, который будет использоваться в качестве перехватавсе для оставшихся запросов.Много это поможет или нет, зависит от объема данных и от того, что именно «несколько часто» означает, в точности.

В более общем смысле, и для решения вашего первоначального вопроса, индексы в MongoDB, как и любая база данных,повысит производительность запросов (для тех запросов, которым они соответствуют) за счет небольшого снижения производительности обновлений / вставок / удалений (поскольку индекс должен быть изменен вместе с базовыми данными).Мой подход заключается в создании индексов для тех запросов, которые, как я знаю, будут либо очень дорогостоящими, либо очень частыми, а затем тестировать с использованием реалистичного распределения нагрузки (т. Е. Реалистичного числа и частоты запросов и обновлений / вставок / удалений), чтобы увидеть, какие другиезапросы обходятся дороже, чем вы ожидаете.Вы можете использовать профилировщик базы данных , чтобы помочь в сборе этой информации, возможно, с помощью инструмента, подобного Professor (#shamelessplug), чтобы помочь в понимании результатов.

...