Mongodb простой префикс запроса с регулярным выражением и сортировка медленная

Я застрял с этим простым запросом префикса. ХотяМонго документы утверждая, что вы можете получить довольно хорошую производительность, используя префиксный формат регулярных выражений (/ ^ a /), запрос довольно медленный, когда я пытаюсь отсортировать результаты:

940 миллис

db.posts.find ({hashtags: / ^ noticias /}). limit (15) .sort ({rank: -1}). hint ('hashtags_1_rank_-1') .Explain ()

{
"cursor" : "BtreeCursor hashtags_1_rank_-1 multi",
"isMultiKey" : true,
"n" : 15,
"nscannedObjects" : 142691,
"nscanned" : 142692,
"nscannedObjectsAllPlans" : 142691,
"nscannedAllPlans" : 142692,
"scanAndOrder" : true,
"indexOnly" : false,
"nYields" : 1,
"nChunkSkips" : 0,
"millis" : 934,
"indexBounds" : {
    "hashtags" : [
        [
            "noticias",
            "noticiat"
        ],
        [
            /^noticias/,
            /^noticias/
        ]
    ],
    "rank" : [
        [
            {
                "$maxElement" : 1
            },
            {
                "$minElement" : 1
            }
        ]
    ]
},
"server" : "XRTZ048.local:27017"
}

Однако несортированная версия того же запроса очень быстрая:

0 миллис

db.posts.find ({hashtags: / ^ noticias /}). limit (15) .hint ('hashtags_1_rank_-1') .Explain ()}

{
"cursor" : "BtreeCursor hashtags_1_rank_-1 multi",
"isMultiKey" : true,
"n" : 15,
"nscannedObjects" : 15,
"nscanned" : 15,
"nscannedObjectsAllPlans" : 15,
"nscannedAllPlans" : 15,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
    "hashtags" : [
        [
            "noticias",
            "noticiat"
        ],
        [
            /^noticias/,
            /^noticias/
        ]
    ],
    "rank" : [
        [
            {
                "$maxElement" : 1
            },
            {
                "$minElement" : 1
            }
        ]
    ]
},
"server" : "XRTZ048.local:27017"

Запрос также выполняется быстро, если я удалю регулярное выражение и отсортирую:

0 миллис

db.posts.find ({hashtags: 'Noticias' }). limit (15) .sort ({rank: -1}). hint ('hashtags_1_rank_-1') .Explain ()}

{
"cursor" : "BtreeCursor hashtags_1_rank_-1",
"isMultiKey" : true,
"n" : 15,
"nscannedObjects" : 15,
"nscanned" : 15,
"nscannedObjectsAllPlans" : 15,
"nscannedAllPlans" : 15,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
    "hashtags" : [
        [
            "noticias",
            "noticias"
        ]
    ],
    "rank" : [
        [
            {
                "$maxElement" : 1
            },
            {
                "$minElement" : 1
            }
        ]
    ]
},
"server" : "XRTZ048.local:27017"

Кажется, использование регулярных выражений и сортировки заставляет Mongo сканировать множество записей. Тем не менее, сортировка сканирует только 15, если я нене использовать регулярное выражение. Какие'здесь не так?

 slee23 окт. 2012 г., 18:22
Хайме, я считаю,scanAndOrder отвечает за медлительность. Вы можете посмотреть наАндреответ что может быть похоже, если не совсем так же, как ваша проблема.

Ответы на вопрос(1)

Решение Вопроса

scanAndOrder: true в выводе объяснения указывает, что запрос должен извлечь документы и затем отсортировать их в памяти, прежде чем вывод будет возвращен. Это дорогостоящая операция, которая будет влиять на производительность вашего запроса.

СуществованиеscanAndOrder: true а также разница вnscanned n в выводе объяснения указывает, что запрос не использует оптимальный индекс. В этом случае, по-видимому, необходимо выполнить сканирование коллекции. Вы можете решить эту проблему, включив в свой индекс ключиsort критерии. Из моего тестирования:

db.posts.find({hashtags: /^noticias/ }).limit(15).sort({hashtags:1, rank : -1}).explain()

Не требует сканирования и заказа, и возвращаетn а такжеnscanned количество записей, которые вы ищете. Это также будет означать сортировку поhashtags ключ, который может или не может быть полезен для вас, но должен повысить производительность запроса.

 Darius16 июн. 2013 г., 13:10
Спасибо, это действительно помогло. Также стоит отметить, что границы индекса выводятся из первого регулярного выражения, если вы добавляете несколько. Например, этот запрос:db.posts.find({"$and" : [{hashtags: /^manana/}, {hashtags: /^noticias/}]}).sort({'hashtags':1,'rank':-1}).limit(10).explain()  будет иметь пределы индекса на манане, и это может иметь разницу производительности. В моем случае сортировка запросов регулярных выражений в алфавитном порядке дала лучшую производительность

Ваш ответ на вопрос