Почему мои индексы не используются только в этом моно-запросе? - PullRequest
1 голос
/ 18 ноября 2011

У меня есть, как мне показалось, довольно простой, простой запрос в Mongo, и я создал индекс:

{ "Ended" : 1, "EndDate" -1 }

Однако, когда я выполняю простой запрос к нему, он, кажется, распознает индекс, но он все еще сканирует МНОГО объектов, чтобы извлечь данные. Вот мой запрос и объясните результаты:

PRIMARY> db.listing.find({ "Ended" : { "$ne" : true }, "EndDate" : { "$lte" : ISODate("2011-11-18T00:47:40.638Z") } }).explain();
{
        "cursor" : "BtreeCursor Ended_1_EndDate_-1 multi",
        "nscanned" : 24508585,
        "nscannedObjects" : 24508583,
        "n" : 24508583,
        "millis" : 108323,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
                "Ended" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                true
                        ],
                        [
                                true,
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ],
                "EndDate" : [
                        [
                                ISODate("2011-11-18T00:47:40.638Z"),
                                true
                        ]
                ]
        }
}

Есть какие-нибудь очевидные идеи, что я делаю не так? Спасибо!

Ответы [ 3 ]

4 голосов
/ 18 ноября 2011

Индексы не очень хороши с запросами $ ne или $ nin. Было бы лучше с

db.listing.find({ "Ended" : false , "EndDate" : { "$lte" : ISODate("2011-11-18T00:47:40.638Z") } })

Разница здесь в том, что вы больше не будете получать документы без поля «Завершено», или если поле «Завершено» имеет значение null или какой-либо другой тип.

Советы по индексированию и часто задаваемые вопросы - MongDOB

2 голосов
/ 18 ноября 2011

Поле n указывает, что ваш запрос соответствует 24,5M документов, то же самое число, что и nscannedObjects, что является нормальным поведением. Если вам не нужны все соответствующие документы размером 24,5 млн., Вы должны добавить дополнительные критерии к вашему запросу.

Я также вижу, что вы используете EndedDate: {$ne: true}. Хотя это будет работать, оно будет медленнее, чем EndedDate: false, поэтому, если это поле возможно только true или false, вам лучше использовать последнее.

0 голосов
/ 18 ноября 2011

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

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

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

...