Монго не попадает в индекс

#mongodb #indexing #mongodb-indexes

Вопрос:

Я пытаюсь обновить около 255 тыс. документов в коллекции mongo объемом около 200 ГБ. Если я запущу план объяснения по запросу, выигрышный план попадет в правильный индекс. Но когда я запускаю скрипт node js, который выполняет тот же запрос, индекс пропущен. Я обнаружил, что этот индекс всегда используется только в том случае, если я добавляю подсказку.

Итак, если я добавлю подсказку, обновление 255 тысяч записей производится за секунды, иначе за часы/дни… 🙂

Мне бы очень хотелось понять, почему монго пропускает индекс, и объяснить простые оценки.

И еще кое-что:

  • Имеет ли значение порядок индексов. Каковы некоторые хорошие практики
  • Должны ли поля в фильтре быть I в том же порядке, что и в индексе
  • Как ведет себя индекс при использовании фильтра neq (не равно)
  • Что делает монго, когда он находит более одного ответа, равного производительности. Выполняет ли он ограничение(1)
  • Как он может пропустить индекс, даже если соответствующий индекс чрезвычайно быстр

Итак, ниже приведен режим данных, существующие индексы и часть сценария js узла.

  //Existing indexes 
  schema.index({ executed: -1, account: 1, status: 1, type: 1, retry: 1, _id: 1 });
  schema.index({ id: 1 });
  schema.index({ status: 1, deleted: 1, account: 1, updatedAt: -1 });
  schema.index({ account: 1, deleted: 1, updatedAt: -1 });
  schema.index({ type: 1, deleted: 1, account: 1 });
  schema.index({ deleted: 1, account: 1, status: 1 });
  schema.index({ willRun: 1, type: 1, deleted: 1 });
  schema.index({ cases: 1, deleted: 1 });
  schema.index({ procedure: 1, deleted: 1, type: 1, scheduled: -1, cases: 1 });
  schema.index({ account: 1, status: 1, executed: 1, type: 1, retry: 1, _id: 1 });

//part of script
        let tasksList = await tasks
            .find(
                {
                    account: mongoose.Types.ObjectId(accountId),
                    status: 0,
                    executed: {
                        $lte: '2020-10-16T06:01:17.171Z' // new Date(deleteDate)
                    },
                    type: {
                        $ne: 'taskForDelete'
                    },
                    retry: {
                        $ne: 5
                    }
                }, { _id: 1 }).hint({ account: 1, status: 1, executed: 1, type: 1, retry: 1, _id: 1 });
 

Комментарии:

1. Попробуйте запустить объяснение с опцией «allPlansExecution», чтобы увидеть, как выполняется каждый индекс при планировании.

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

3. Когда это занимает много времени, в журнале должна быть запись. Какой индекс, как показывает эта строка журнала, был использован?