MongoDB регулярное выражение с индексированным полем - PullRequest
22 голосов
/ 12 ноября 2011

Я создавал свое первое приложение, используя 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 Ответ

13 голосов
/ 07 июля 2012

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

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

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

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

...