время поиска с индексом> без индекса - PullRequest
3 голосов
/ 20 марта 2012

У меня есть одна коллекция «чисел» с 200000 объектами документа с {number: i} i = от 1 до 200000.

Без индекса $ gt: 10000 дает сканированные 200000 и 115 мс. С индексом по номеру $ gt: 10000 дает сканированные 189999 и 355 мс.

Почему больше времени на индексацию?

> db.numbers.find({number: {$gt: 10000}}).explain()
{
    "cursor" : "BasicCursor",
    "nscanned" : 200000,
    "nscannedObjects" : 200000,
    "n" : 189999,
    "millis" : 115,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {

    }
}

> db.numbers.ensureIndex({number: 1})

> db.numbers.find({number: {$gt: 10000}}).explain()
{
    "cursor" : "BtreeCursor number_1",
    "nscanned" : 189999,
    "nscannedObjects" : 189999,
    "n" : 189999,
    "millis" : 355,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
            "number" : [
                    [
                            10000,
                            1.7976931348623157e+308
                    ]
            ]
    }
}

1 Ответ

5 голосов
/ 20 марта 2012

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

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

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

Добавление .limit () ускорит запрос.Вы также можете заставить оптимизатор запросов не использовать индекс с помощью .hint ():

db.collection.find().hint({$natural:1})

Вы также можете заставить запрос предоставлять значения результата непосредственно из самого индекса, ограничивая выбранные поля толькоте, которые вы проиндексировали.Это позволяет избежать необходимости загружать какие-либо документы после сканирования индекса.

Попробуйте сделать это и посмотрите, показывает ли вывод объяснения "indexOnly":true

db.numbers.find({number: {$gt: 10000}}, {number:1}).explain()

Подробности здесь:

http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields#RetrievingaSubsetofFields-CoveredIndexes

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...