Можно ли использовать составной индекс при поиске одного поля в MongoDB?
Если я создаю следующий составной индекс:
{'username': 1, 'uid': 1}
Можно ли использовать этот индекс, если я буду искать только с uid
, лайкdb.users.find({'uid': '12345'})
?
Потому что для генерации двух отдельных индексов требуется больше памяти.
4 ответа
Пока вы запрашиваете поля, которые являются левым подмножеством индексированных полей, MongoDB будет автоматически использовать индекс. То есть, если у вас есть такой индекс, как {a:1, b:1, c:1}, все 3 запроса db.coll.find({a:"xxx"}), db.coll.find({a:"xxx", b:"yyy"}) и db.coll.find({a:"xxx", b:"yyy", c:"zzz"}) будут использовать этот индекс, предполагая, что нет другие показатели.
Это можно с помощью hint()
однако оптимизатор не будет выбирать этот индекс по умолчанию, поскольку он выполняет поиск по префиксу и uid
не является префиксом {username, uid}
,
Что касается использования индекса при поиске, он будет сканировать все username
значения, а затем отсканируйте uid
в каждом имени пользователя.
Иногда это может быть хорошо, особенно если вы хотите отсортировать uid
значения по username
, поскольку scanandorder
будет false
но если вы не собираетесь сортировать по username
поля, то вы могли бы найти, что он может стать немного несоответствующим.
Ответ - нет, mongo не будет использовать этот составной индекс, когда вы найдете его по uid.
Ваш индекс будет использоваться, когда вы попытаетесь найти по имени пользователя или по паре имени пользователя и uid. Это хорошо описано в документации mongo:https://docs.mongodb.com/manual/core/index-compound/
Если вы предпочитаете поиск по uid вместо имени пользователя, вам следует изменить порядок в своем составном индексе.
Если вы не выполняете поиск по имени пользователя и uid одновременно, лучший вариант - удалить этот составной индекс и создать два отдельных индекса.
Если ваш индекс: {a:1,b:1, c: 1}.
Затем он будет применяться для следующих условий:
db.coll.find({a:'xxx'})
db.coll.find({b:'yyyy'})
db.coll.find({c:'zzz'})
db.coll.find({a:'xxx',c:'zzz'})
db.coll.find({a:'xxx',b:'yyy'})
db.coll.find({a:'xxx',b:'yyy',c:'zzz'})
db.coll.find({b:'yyy',a:'xxx',c:'zzz'})
db.coll.find({b:'yyy',c:'zzz',a:'xxx'})
Он не будет работать в следующих условиях:
db.coll.find({b:'yyy',c:'zzz'})
db.coll.find({b:'yyy'})
db.coll.find({c:'zzz'})
Индексы работают только в том случае, если ваш префикс индекса находится в вашем поисковом запросе. Порядок не имеет значения.