MongoDB индексирует 2 поля и позволяет использовать индекс для поиска по 3-му полю

Из документации MongoDB

Если у вас есть составной индекс для нескольких полей, вы можете использовать его для запроса начального подмножества полей. Итак, если у вас есть индекс для a, b, c, вы можете использовать его для запроса [a] [a, b] [a, b, c]

Допустим, у меня есть документ с этими полями

  1. Логин пользователя
  2. Имя
  3. Страна
  4. Экстрафилд

Порядок моего индекса: [ID пользователя, имя, страна]

Итак, если у меня есть запрос типа

  var q = (from c in collection.AsQueryable()
                 where c.UserID == UserID
                 where Name = "test"
                 where Country = 1
                 where ExtraField = "check"

                 select c);

Использует ли этот запрос индекс для первых трех параметров, а затем ищет ExtraField без индекса?

Если да, то то же самое и в этом запросе

 var q = (from c in collection.AsQueryable()
                 where c.UserID == UserID                   
                 where ExtraField = "check"

                 select c);

person Novkovski Stevo Bato    schedule 05.09.2012    source источник
comment
Он должен иметь возможность использовать индекс в этих двух запросах. Я не использую драйвер С#, можете ли вы просмотреть планы объяснения там (или вы можете увидеть в журналах приложений, какой именно запрос отправляется в базу данных)?   -  person Sergio Tulentsev    schedule 05.09.2012


Ответы (1)


Ответ на оба вопроса — да.

Для вашего первого запроса производительность будет зависеть от селективности набора результатов. Таким образом, если бы 3 поля в индексе соответствовали очень большому количеству документов, производительность была бы низкой, поскольку все эти документы необходимо было бы отсканировать, чтобы найти совпадения в ExtraField. Если бы было сопоставлено только несколько документов, производительность была бы быстрой.

Теперь, если ваш запрос вообще не включает первое поле в индекс, индекс не будет использоваться. Например, следующий запрос не сможет использовать индекс:

var q = (from c in collection.AsQueryable()
              where Name = "test"
              where Country = 1
              select c);

Посмотрите здесь некоторые интересные факты о поиске других комбинаций полей в индексе.

Я бы рекомендовал используйте команду объяснения, когда сомневаетесь в подобных вопросах.

person Zaid Masud    schedule 05.09.2012
comment
Для первого запроса мое предположение для всех документов по UserID - это числа (60% между 0-400, 20% между 401-1000, 15% между 1001-2000, еще 5%). По вашему опыту, это медленно? - person Novkovski Stevo Bato; 05.09.2012
comment
@NovkovskiStevoBato Нет, я не думаю, что это будет слишком медленно. Посмотрите на nscanned в вашей команде объяснения, вы хотите, чтобы он был как можно меньше. Вы же не хотите, чтобы число nscanned составляло десятки тысяч. Если это иногда тысячи, это будет несколько медленно, но все же может быть приемлемым. Если это сотни, это будет очень быстро. - person Zaid Masud; 05.09.2012