2014-07-13 4 views
2

Возьмите, например, find(), который включает в себя поле a и b, в указанном порядке. Например,Какой индекс будет использоваться, если имеется несколько индексов, содержащих одни и те же поля?

db.collection.find({'a':{'$lt':10},'b':{'$lt':5}}) 

У меня есть два ключа в моем массиве индексов для коллекции:

[ 
{ 
    "v" : 1, 
    "key" : { 
     "a" : 1, 
     "b" : 1 
    }, 
    "ns" : "x.test", 
    "name" : "a_1_b_1" 
}, 
{ 
    "v" : 1, 
    "key" : { 
     "a" : 1, 
     "b" : 1, 
     "c" : 1 
    }, 
    "ns" : "x.test", 
    "name" : "a_1_b_1_c_1" 
} 
] 

Это гарантировано что Монго будет использовать первый ключ, так как он более точно соответствует запросу, или он случайно выбирает любой из двух ключей, потому что они оба будут работать?

+0

может показать нам ваши индексы? – Zarathustra

+0

Обновлен мой вопрос с фактическим массивом (не считалось, что это было необходимо раньше) – ujvl

+0

Стоит отметить, что вы можете удалить свой первый индекс ('a_1_b_1'), поскольку он является надлежащим подмножеством второго индекса (такие же ключи и порядок) который может использоваться для удовлетворения тех же запросов. Дублирующие индексы - лишние накладные расходы. – Stennie

ответ

4

MongoDB имеет оптимизатор запросов, который выбирает индексы, которые являются наиболее эффективными. Из docs:

Оптимизатор запросов MongoDB обрабатывает запросы и выбирает эффективный план запроса наиболее для запроса с учетом имеющихся индексов.

Таким образом, это не является строго гарантированным (но я ожидаю, что меньший индекс даст результаты быстрее, чем больший составной индекс). Вы также можете использовать оператор hint, чтобы заставить оптимизатор запросов использовать указанный индекс.

db.collection.find({'a':{'$lt':10},'b':{'$lt':5}}).hint({a:1, b:1}); 

Однако эти два индекса в вашем примере являются избыточными. Это связано с тем, что составной индекс поддерживает запросы на любые поля prefix of index.

Следующий индекс:

db.collection.ensureIndex({a: 1, b: 1, c: 1}); 

Может поддерживать запросы, которые включают в себя a, a и b и a и b и c, но не только b или c, или только b и c.

+1

Yup, я понимаю избыточность ... Мне было просто любопытно, что ** ЕСЛИ ** оба присутствовали, что бы выбрали (что вы ответили). – ujvl

0

Вы используете $ exist ,, When is true, $ exists соответствует документам, содержащим это поле, включая документы, где значение поля равно null. Если false, запрос возвращает только документы, которые не содержат это поле.

$exist

запрос будет

db.inventory.find({ "key.a": { $exists: true, 1 },"key.b": { $exists: true, 1 } }) 
+0

Я думаю, что вы, возможно, неправильно поняли мой вопрос (или я ваш ответ) ... Я хочу знать, какой индекс будет использоваться ... тот, у которого есть первый ключ или второй со вторым в ситуации, когда это возможно при выполнении команды 'find' или' sort'. – ujvl

+0

«ключ» - это поле внутри массива индексов, которое имеет коллекция. Например, когда я говорю «дБ.collection.ensureIndex ({a: 1, b: 1}) ' – ujvl

+0

ключ - это массив или json document .. коллекции? –