Регулярное выражение MongoDB с индексированным полем

Я создавал свое первое приложение с помощью MongoDB. Создал индекс для поля и попытался найти запрос с параметром $regex, запущенным в оболочке

> db.foo.find({A:{$regex:'BLABLA!25500[0-9]'}}).explain()
{
        "cursor" : "BtreeCursor A_1 multi",
        "nscanned" : 500001,
        "nscannedObjects" : 10,
        "n" : 10,
        "millis" : 956,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
                "A" : [
                        [
                                "",
                                {

                                }
                        ],
                        [
                                /BLABLA!25500[0-9]/,
                                /BLABLA!25500[0-9]/
                        ]
                ]
        }
}

Это очень странно, потому что, когда я запускаю тот же запрос, но без индекса в коллекции, производительность намного лучше.

> db.foo.find({A:{$regex:'BLABLA!25500[0-9]'}}).explain()
{
        "cursor" : "BasicCursor",
        "nscanned" : 500002,
        "nscannedObjects" : 500002,
        "n" : 10,
        "millis" : 531,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {

        }
}

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

Ответ 1

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

Когда вы удаляете индекс, вы просто выполняете сканирование таблицы и сопоставляете регулярное выражение там - по сути, вы упростили вещи от первого.

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

Когда вы используете префиксный запрос, это не значит, что он использует только индекс, но вы используете индекс эффективно, что является ключевым, и, следовательно, вы видите реальный прирост производительности.