Пн go использование неверного индекса при агрегации с операциями сопоставления + сортировки - PullRequest
1 голос
/ 14 января 2020

Я использую версию MongoDB 4.2.0. У меня есть коллекция со следующими индексами:

{uuid: 1},
{unique: true, name: "uuid_idx"}

и

{field1: 1, field2: 1, _id: 1},
{unique: true, name: "compound_idx"}

При выполнении этого запроса

aggregate([
  {"$match": {"uuid": <uuid_value>}}
])

планировщик правильно выбирает uuid_idx.

При добавлении этого условия сортировки

aggregate([
  {"$match": {"uuid": <uuid_value>}},
  {"$sort": {"field1": 1, "field2": 1, "_id": 1}}
])

планировщик выбирает compound_idx, что замедляет запрос.

Я ожидаю, что предложение сортировки не будет иметь значения в этот контекст. Почему Mon go не использует индекс uuid_idx в обоих случаях ?

EDIT : Небольшое уточнение, я понимаю, что есть обходные пути для использования правильного Индекс, но я ищу объяснение, почему это не происходит автоматически (если возможно, со ссылками на официальную документацию). Спасибо!

Ответы [ 2 ]

0 голосов
/ 15 января 2020

Запрос:

aggregate( 
  [
    { $match : { uuid : "some_value" } },
    { $sort : { fld1: 1, fld2: 1, _id: 1 } }
  ],
)

не использует индекс "uuid_idx".

Есть несколько опций, с которыми вы можете работать для использования индексов в обоих совпадениях и операции сортировки :


(1) Определить новый составной индекс: {uuid: 1, fld1: 1, fld2: 1, _id: 1 }

Оба запроса match и match + sort будут использовать этот индекс (как для операций сравнения, так и для операций сортировки).


(2) Использовать подсказку для индекса uuid (с использованием существующих индексов)

Оба match и match + sort запросов будет использовать этот индекс (как для сопоставления, так и для операций сортировки).

aggregate( 
  [
    { $match : { uuid : "some_value" } },
    { $sort : { fld1: 1, fld2: 1, _id: 1 } }
  ],
  { hint: "uuid_idx"}
)
0 голосов
/ 14 января 2020

Почему это происходит ?:

Давайте разберемся, как Mon go выбирает какой индекс использовать, как объяснено здесь .

Если запрос может быть удовлетворен несколькими индексами (удовлетворен, используется бесполезно, поскольку Mon go фактически выбирает все возможные релевантные индексы), определенные в коллекции.

MongoDB затем будет тестировать все применимые индексы параллельно. Первый индекс, который может вернуть 101 результат, будет выбран планировщиком запросов.

Это означает, что для этого определенного запроса этот индекс действительно выигрывает.

Что мы можем сделать?:

Мы можем использовать $ hint , подсказка в основном заставляет Mon go использовать заданный индекс c, однако Mon go это не рекомендуется, потому что если изменения происходят Mon go не приспособится к этим.

...